diff options
56 files changed, 922 insertions, 1007 deletions
| diff --git a/.travis.yml b/.travis.yml index aea2b8ed0a..cbba07b16d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,9 @@ before_script:  script:    - travis/phing-sniff.sh $DB $TRAVIS_PHP_VERSION +  - travis/check-sami-parse-errors.sh $DB $TRAVIS_PHP_VERSION    - travis/check-image-icc-profiles.sh $DB $TRAVIS_PHP_VERSION +  - travis/check-executable-files.sh $DB $TRAVIS_PHP_VERSION ./    - phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml    - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3.3' -a '$DB' = 'mysqli' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi" diff --git a/build/sami.conf.php b/build/sami.conf.php index febd0276d4..78d532631c 100644 --- a/build/sami.conf.php +++ b/build/sami.conf.php @@ -45,7 +45,7 @@ $versions = Sami\Version\GitVersionCollection::create(__DIR__ . '/../')  	->add('develop-ascraeus')  ; -return new Sami\Sami($iterator, array( +$config = array(  	'theme'                => 'enhanced',  	'versions'             => $versions,  	'title'                => 'phpBB API Documentation', @@ -54,4 +54,6 @@ return new Sami\Sami($iterator, array(  	'default_opened_level' => 2,  	// Do not use JsonStore. See https://github.com/fabpot/Sami/issues/79  	'store'                => new PhpbbArrayStore, -)); +); + +return new Sami\Sami($iterator, $config); diff --git a/phpBB/composer.json b/phpBB/composer.json index 0ab30b0837..e74dd120f0 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -37,8 +37,6 @@  		"twig/twig": "1.13.*"  	},  	"require-dev": { -		"behat/mink": "1.4.*", -		"behat/mink-goutte-driver": "1.0.*",  		"fabpot/goutte": "1.0.*",  		"phpunit/dbunit": "1.3.*",  		"phpunit/phpunit": "4.1.*", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 3860a98b31..671daa70e1 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -3,7 +3,7 @@          "This file locks the dependencies of your project to a known state",          "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"      ], -    "hash": "6bc742a2b9feb426db9987d27085f915", +    "hash": "27d5da149e0b5d76b76f43210306b666",      "packages": [          {              "name": "lusitanian/oauth", @@ -255,12 +255,14 @@              ],              "authors": [                  { -                    "name": "Symfony Community", -                    "homepage": "http://symfony.com/contributors" +                    "name": "Fabien Potencier", +                    "email": "fabien@symfony.com", +                    "homepage": "http://fabien.potencier.org", +                    "role": "Lead Developer"                  },                  { -                    "name": "Fabien Potencier", -                    "email": "fabien@symfony.com" +                    "name": "Symfony Community", +                    "homepage": "http://symfony.com/contributors"                  }              ],              "description": "Symfony Debug Component", @@ -719,167 +721,6 @@      ],      "packages-dev": [          { -            "name": "behat/mink", -            "version": "v1.4.3", -            "source": { -                "type": "git", -                "url": "https://github.com/Behat/Mink.git", -                "reference": "0817070a6e2ec9f475fad9bfb81a962c462eb934" -            }, -            "dist": { -                "type": "zip", -                "url": "https://api.github.com/repos/Behat/Mink/zipball/0817070a6e2ec9f475fad9bfb81a962c462eb934", -                "reference": "0817070a6e2ec9f475fad9bfb81a962c462eb934", -                "shasum": "" -            }, -            "require": { -                "php": ">=5.3.1", -                "symfony/css-selector": ">=2.0,<2.4-dev" -            }, -            "suggest": { -                "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", -                "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", -                "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", -                "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)" -            }, -            "type": "library", -            "extra": { -                "branch-alias": { -                    "dev-develop": "1.4.x-dev" -                } -            }, -            "autoload": { -                "psr-0": { -                    "Behat\\Mink": "src/" -                } -            }, -            "notification-url": "https://packagist.org/downloads/", -            "license": [ -                "MIT" -            ], -            "authors": [ -                { -                    "name": "Konstantin Kudryashov", -                    "email": "ever.zet@gmail.com", -                    "homepage": "http://everzet.com" -                } -            ], -            "description": "Web acceptance testing framework for PHP 5.3", -            "homepage": "http://mink.behat.org/", -            "keywords": [ -                "browser", -                "testing", -                "web" -            ], -            "time": "2013-03-02 15:53:18" -        }, -        { -            "name": "behat/mink-browserkit-driver", -            "version": "v1.0.5", -            "source": { -                "type": "git", -                "url": "https://github.com/Behat/MinkBrowserKitDriver.git", -                "reference": "f2771b5fc4dbc233859addf37a7d150852f78418" -            }, -            "dist": { -                "type": "zip", -                "url": "https://api.github.com/repos/Behat/MinkBrowserKitDriver/zipball/f2771b5fc4dbc233859addf37a7d150852f78418", -                "reference": "f2771b5fc4dbc233859addf37a7d150852f78418", -                "shasum": "" -            }, -            "require": { -                "behat/mink": "~1.4.3", -                "php": ">=5.3.1", -                "symfony/browser-kit": "~2.0", -                "symfony/dom-crawler": "~2.0" -            }, -            "require-dev": { -                "silex/silex": "@dev" -            }, -            "type": "mink-driver", -            "extra": { -                "branch-alias": { -                    "dev-master": "1.0.x-dev" -                } -            }, -            "autoload": { -                "psr-0": { -                    "Behat\\Mink\\Driver": "src/" -                } -            }, -            "notification-url": "https://packagist.org/downloads/", -            "license": [ -                "MIT" -            ], -            "authors": [ -                { -                    "name": "Konstantin Kudryashov", -                    "email": "ever.zet@gmail.com", -                    "homepage": "http://everzet.com" -                } -            ], -            "description": "Symfony2 BrowserKit driver for Mink framework", -            "homepage": "http://mink.behat.org/", -            "keywords": [ -                "Mink", -                "Symfony2", -                "browser", -                "testing" -            ], -            "time": "2013-04-13 12:17:15" -        }, -        { -            "name": "behat/mink-goutte-driver", -            "version": "v1.0.9", -            "source": { -                "type": "git", -                "url": "https://github.com/Behat/MinkGoutteDriver.git", -                "reference": "fa1b073b48761464feb0b05e6825da44b20118d8" -            }, -            "dist": { -                "type": "zip", -                "url": "https://api.github.com/repos/Behat/MinkGoutteDriver/zipball/fa1b073b48761464feb0b05e6825da44b20118d8", -                "reference": "fa1b073b48761464feb0b05e6825da44b20118d8", -                "shasum": "" -            }, -            "require": { -                "behat/mink-browserkit-driver": ">=1.0.5,<1.2.0", -                "fabpot/goutte": "~1.0.1", -                "php": ">=5.3.1" -            }, -            "type": "mink-driver", -            "extra": { -                "branch-alias": { -                    "dev-master": "1.0.x-dev" -                } -            }, -            "autoload": { -                "psr-0": { -                    "Behat\\Mink\\Driver": "src/" -                } -            }, -            "notification-url": "https://packagist.org/downloads/", -            "license": [ -                "MIT" -            ], -            "authors": [ -                { -                    "name": "Konstantin Kudryashov", -                    "email": "ever.zet@gmail.com", -                    "homepage": "http://everzet.com" -                } -            ], -            "description": "Goutte driver for Mink framework", -            "homepage": "http://mink.behat.org/", -            "keywords": [ -                "browser", -                "goutte", -                "headless", -                "testing" -            ], -            "time": "2013-07-03 18:43:54" -        }, -        {              "name": "fabpot/goutte",              "version": "v1.0.3",              "source": { @@ -2428,11 +2269,17 @@              "time": "2014-05-17 21:49:26"          }      ], -    "aliases": [], +    "aliases": [ + +    ],      "minimum-stability": "stable", -    "stability-flags": [], +    "stability-flags": [ + +    ],      "platform": {          "php": ">=5.3.3"      }, -    "platform-dev": [] +    "platform-dev": [ + +    ]  } diff --git a/phpBB/download/file.php b/phpBB/download/file.php index d4e0f04d2b..984de2165f 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -11,10 +11,6 @@  *  */ -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -  /**  * @ignore  */ @@ -143,11 +139,7 @@ if (isset($_GET['avatar']))  include($phpbb_root_path . 'common.' . $phpEx);  require($phpbb_root_path . 'includes/functions_download' . '.' . $phpEx); -$download_id = request_var('id', 0); -$topic_id = $request->variable('topic_id', 0); -$post_id = $request->variable('post_id', 0); -$msg_id = $request->variable('msg_id', 0); -$archive = $request->variable('archive', '.tar'); +$attach_id = request_var('id', 0);  $mode = request_var('mode', '');  $thumbnail = request_var('t', false); @@ -162,27 +154,7 @@ if (!$config['allow_attachments'] && !$config['allow_pm_attach'])  	trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');  } -if ($download_id) -{ -	// Attachment id (only 1 attachment) -	$sql_where = 'attach_id = ' . $download_id; -} -else if ($msg_id) -{ -	// Private message id (multiple attachments) -	$sql_where = 'is_orphan = 0 AND in_message = 1 AND post_msg_id = ' . $msg_id; -} -else if ($post_id) -{ -	// Post id (multiple attachments) -	$sql_where = 'is_orphan = 0 AND in_message = 0 AND post_msg_id = ' . $post_id; -} -else if ($topic_id) -{ -	// Topic id (multiple attachments) -	$sql_where = 'is_orphan = 0 AND topic_id = ' . $topic_id; -} -else +if (!$attach_id)  {  	send_status_line(404, 'Not Found');  	trigger_error('NO_ATTACHMENT_SELECTED'); @@ -190,25 +162,12 @@ else  $sql = 'SELECT attach_id, post_msg_id, topic_id, in_message, poster_id, is_orphan, physical_filename, real_filename, extension, mimetype, filesize, filetime  	FROM ' . ATTACHMENTS_TABLE . " -	WHERE $sql_where"; +	WHERE attach_id = $attach_id";  $result = $db->sql_query($sql); - -$attachments = $attachment_ids = array(); -while ($row = $db->sql_fetchrow($result)) -{ -	$attachment_id = (int) $row['attach_id']; - -	$row['physical_filename'] = utf8_basename($row['physical_filename']); - -	$attachment_ids[$attachment_id] = $attachment_id; -	$attachments[$attachment_id] = $row; -} +$attachment = $db->sql_fetchrow($result);  $db->sql_freeresult($result); -// Make $attachment the first of the attachments we fetched. -$attachment = current($attachments); - -if (empty($attachments)) +if (!$attachment)  {  	send_status_line(404, 'Not Found');  	trigger_error('ERROR_NO_ATTACHMENT'); @@ -218,9 +177,9 @@ else if (!download_allowed())  	send_status_line(403, 'Forbidden');  	trigger_error($user->lang['LINKAGE_FORBIDDEN']);  } -else if ($download_id) +else  { -	// sizeof($attachments) == 1 +	$attachment['physical_filename'] = utf8_basename($attachment['physical_filename']);  	if (!$attachment['in_message'] && !$config['allow_attachments'] || $attachment['in_message'] && !$config['allow_pm_attach'])  	{ @@ -327,142 +286,3 @@ else if ($download_id)  		}  	}  } -else -{ -	// sizeof($attachments) >= 1 -	if ($attachment['in_message']) -	{ -		phpbb_download_handle_pm_auth($db, $auth, $user->data['user_id'], $attachment['post_msg_id']); -	} -	else -	{ -		phpbb_download_handle_forum_auth($db, $auth, $attachment['topic_id']); -	} - -	if (!class_exists('compress')) -	{ -		require $phpbb_root_path . 'includes/functions_compress.' . $phpEx; -	} - -	if (!in_array($archive, compress::methods())) -	{ -		$archive = '.tar'; -	} - -	$post_visibility = array(); -	if ($msg_id) -	{ -		$sql = 'SELECT message_subject AS attach_subject -			FROM ' . PRIVMSGS_TABLE . " -			WHERE msg_id = $msg_id"; -	} -	else if ($post_id) -	{ -		$sql = 'SELECT post_subject AS attach_subject, forum_id, post_visibility -			FROM ' . POSTS_TABLE . " -			WHERE post_id = $post_id"; -	} -	else -	{ -		$sql = 'SELECT post_id, post_visibility -			FROM ' . POSTS_TABLE . " -			WHERE topic_id = $topic_id -				AND post_attachment = 1"; -		$result = $db->sql_query($sql); -		while ($row = $db->sql_fetchrow($result)) -		{ -			$post_visibility[(int) $row['post_id']] = (int) $row['post_visibility']; -		} -		$db->sql_freeresult($result); - -		$sql = 'SELECT topic_title AS attach_subject, forum_id -			FROM ' . TOPICS_TABLE . " -			WHERE topic_id = $topic_id"; -	} - -	$result = $db->sql_query($sql); -	$row = $db->sql_fetchrow($result); -	$db->sql_freeresult($result); - -	if (empty($row)) -	{ -		send_status_line(404, 'Not Found'); -		trigger_error('ERROR_NO_ATTACHMENT'); -	} - -	$clean_name = phpbb_download_clean_filename($row['attach_subject']); -	$suffix = '_' . (($msg_id) ? 'm' . $msg_id : (($post_id) ? 'p' . $post_id : 't' . $topic_id)) . '_' . $clean_name; -	$archive_name = 'attachments' . $suffix; - -	$store_name = 'att_' . time() . '_' . unique_id(); -	$archive_path = "{$phpbb_root_path}store/{$store_name}{$archive}"; - -	if ($archive === '.zip') -	{ -		$compress = new compress_zip('w', $archive_path); -	} -	else -	{ -		$compress = new compress_tar('w', $archive_path, $archive); -	} - -	$extensions = array(); -	$files_added = 0; -	$forum_id = ($attachment['in_message']) ? false : (int) $row['forum_id']; -	$disallowed_extension = array(); - -	foreach ($attachments as $attach) -	{ -		if (!extension_allowed($forum_id, $attach['extension'], $extensions)) -		{ -			$disallowed_extension[$attach['extension']] = $attach['extension']; -			continue; -		} - -		if ($post_id && $row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $forum_id)) -		{ -			// Attachment of a soft deleted post and the user is not allowed to see the post -			continue; -		} - -		if ($topic_id && (!isset($post_visibility[$attach['post_msg_id']]) || $post_visibility[$attach['post_msg_id']] != ITEM_APPROVED) && !$auth->acl_get('m_approve', $forum_id)) -		{ -			// Attachment of a soft deleted post and the user is not allowed to see the post -			continue; -		} - -		$prefix = ''; -		if ($topic_id) -		{ -			$prefix = $attach['post_msg_id'] . '_'; -		} - -		$compress->add_custom_file("{$phpbb_root_path}files/{$attach['physical_filename']}", "{$prefix}{$attach['real_filename']}"); -		$files_added++; -	} - -	$compress->close(); - -	if ($files_added) -	{ -		phpbb_increment_downloads($db, $attachment_ids); -		$compress->download($store_name, $archive_name); -	} - -	unlink($archive_path); - -	if (!$files_added && !empty($disallowed_extension)) -	{ -		// None of the attachments had a valid extension -		$disallowed_extension = implode($user->lang['COMMA_SEPARATOR'], $disallowed_extension); -		send_status_line(403, 'Forbidden'); -		trigger_error($user->lang('EXTENSION_DISABLED_AFTER_POSTING', $disallowed_extension)); -	} -	else if (!$files_added) -	{ -		send_status_line(404, 'Not Found'); -		trigger_error('ERROR_NO_ATTACHMENT'); -	} - -	file_gc(); -} diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 4318b20b97..bd0a5795b1 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5095,9 +5095,10 @@ function phpbb_check_and_display_sql_report(\phpbb\request\request_interface $re  * @param \phpbb\config\config				$config		Config object  * @param \phpbb\auth\auth					$auth		Auth object  * @param \phpbb\user						$user		User object +* @param \phpbb\event\dispatcher_interface	$phpbb_dispatcher	Event dispatcher  * @return string  */ -function phpbb_generate_debug_output(phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user) +function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher)  {  	$debug_info = array(); @@ -5136,6 +5137,17 @@ function phpbb_generate_debug_output(phpbb\db\driver\driver_interface $db, \phpb  		}  	} +	/** +	* Modify debug output information +	* +	* @event core.phpbb_generate_debug_output +	* @var	array	debug_info		Array of strings with debug information +	* +	* @since 3.1.0-RC3 +	*/ +	$vars = array('debug_info'); +	extract($phpbb_dispatcher->trigger_event('core.phpbb_generate_debug_output', compact($vars))); +  	return implode(' | ', $debug_info);  } @@ -5174,7 +5186,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =  	phpbb_check_and_display_sql_report($request, $auth, $db);  	$template->assign_vars(array( -		'DEBUG_OUTPUT'			=> phpbb_generate_debug_output($db, $config, $auth, $user), +		'DEBUG_OUTPUT'			=> phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher),  		'TRANSLATION_INFO'		=> (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',  		'CREDIT_LINE'			=> $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited'), diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index ad5a359710..dc3d745d53 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -149,7 +149,7 @@ function adm_page_footer($copyright_html = true)  	phpbb_check_and_display_sql_report($request, $auth, $db);  	$template->assign_vars(array( -		'DEBUG_OUTPUT'		=> phpbb_generate_debug_output($db, $config, $auth, $user), +		'DEBUG_OUTPUT'		=> phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher),  		'TRANSLATION_INFO'	=> (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',  		'S_COPYRIGHT_HTML'	=> $copyright_html,  		'CREDIT_LINE'		=> $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited'), @@ -655,3 +655,30 @@ function validate_range($value_ary, &$error)  		}  	}  } + +/** +* Inserts new config display_vars into an exisiting display_vars array +* at the given position. +* +* @param array $display_vars An array of existing config display vars +* @param array $add_config_vars An array of new config display vars +* @param array $where Where to place the new config vars, +*              before or after an exisiting config, as an array +*              of the form: array('after' => 'config_name') or +*              array('before' => 'config_name'). +* @return array The array of config display vars +*/ +function phpbb_insert_config_array($display_vars, $add_config_vars, $where) +{ +	if (is_array($where) && array_key_exists(current($where), $display_vars)) +	{ +		$position = array_search(current($where), array_keys($display_vars)) + ((key($where) == 'before') ? 0 : 1); +		$display_vars = array_merge( +			array_slice($display_vars, 0, $position), +			$add_config_vars, +			array_slice($display_vars, $position) +		); +	} + +	return $display_vars; +} diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 62f218cf60..78137d075b 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1421,44 +1421,6 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank  }  /** -* Generate a list of archive types available for compressing attachments -* -* @param string $param_key Either topic_id or post_id -* @param string $param_val The value of the topic or post id -* @param string $phpbb_root_path The root path of the phpBB installation -* @param string $phpEx The PHP file extension -* -* @return array Array containing the link and the type of compression -*/ -function phpbb_gen_download_links($param_key, $param_val, $phpbb_root_path, $phpEx) -{ -	if (!class_exists('compress')) -	{ -		require $phpbb_root_path . 'includes/functions_compress.' . $phpEx; -	} - -	$methods = compress::methods(); -	// Sort by preferred type. -	$methods = array_intersect(array('.zip', '.tar.bz2', '.tar.gz', '.tar'), $methods); -	$links = array(); - -	foreach ($methods as $method) -	{ -		$exploded = explode('.', $method); -		$type = array_pop($exploded); -		$params = array('archive' => $method); -		$params[$param_key] = $param_val; - -		$links[] = array( -			'LINK' => append_sid("{$phpbb_root_path}download/file.$phpEx", $params), -			'TYPE' => $type, -		); -	} - -	return $links; -} - -/**  * Prepare profile data  */  function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false) diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index 7a7efd5b34..4ff3994f4c 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -718,27 +718,6 @@ function phpbb_download_check_pm_auth($db, $user_id, $msg_id)  }  /** -* Cleans a filename of any characters that could potentially cause a problem on -* a user's filesystem. -* -* @param string $filename The filename to clean -* -* @return string The cleaned filename -*/ -function phpbb_download_clean_filename($filename) -{ -	$bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|'); - -	// rawurlencode to convert any potentially 'bad' characters that we missed -	$filename = rawurlencode(str_replace($bad_chars, '_', $filename)); - -	// Turn the %xx entities created by rawurlencode to _ -	$filename = preg_replace("/%(\w{2})/", '_', $filename); - -	return $filename; -} - -/**  * Check if the browser is internet explorer version 7+  *  * @param string $user_agent	User agent HTTP header diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index fb09bc7057..624ce187b9 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1324,18 +1324,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $  			{  				delete_topics('topic_id', array($topic_id), false); -				if ($data['topic_visibility'] == ITEM_APPROVED) -				{ -					$sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; -				} -				else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) -				{ -					$sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; -				} -				else if ($data['topic_visibility'] == ITEM_DELETED) -				{ -					$sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1'; -				} +				$phpbb_content_visibility->remove_topic_from_statistic($data, $sql_data);  				$update_sql = update_post_information('forum', $forum_id, true);  				if (sizeof($update_sql)) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index e973e6ec28..a0a67ccf3d 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -586,6 +586,7 @@ class fileupload  	* Upload file from users harddisk  	*  	* @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) +	* @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser  	* @param \phpbb\plupload\plupload $plupload The plupload object  	*  	* @return object $file Object "filespec" is returned, all further operations can be done with this object @@ -743,6 +744,7 @@ class fileupload  	* Uploads file from given url  	*  	* @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif +	* @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser  	* @return object $file Object "filespec" is returned, all further operations can be done with this object  	* @access public  	*/ diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 9f6125f256..92000c6ceb 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1114,6 +1114,7 @@ function mcp_fork_topic($topic_ids)  	$forum_id = request_var('f', 0);  	$redirect = request_var('redirect', build_url(array('action', 'quickmod')));  	$additional_msg = $success_msg = ''; +	$counter = array();  	$s_hidden_fields = build_hidden_fields(array(  		'topic_id_list'	=> $topic_ids, @@ -1306,9 +1307,20 @@ function mcp_fork_topic($topic_ids)  					'post_edit_time'	=> (int) $row['post_edit_time'],  					'post_edit_count'	=> (int) $row['post_edit_count'],  					'post_edit_locked'	=> (int) $row['post_edit_locked'], -					'post_postcount'	=> 0, +					'post_postcount'	=> $row['post_postcount'],  				); - +				// Adjust post count only if the post can be incremented to the user counter +				if ($row['post_postcount']) +				{ +					if (isset($counter[$row['poster_id']])) +					{ +						++$counter[$row['poster_id']]; +					} +					else +					{ +						$counter[$row['poster_id']] = 1; +					} +				}  				$db->sql_query('INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));  				$new_post_id = $db->sql_nextid(); @@ -1428,6 +1440,18 @@ function mcp_fork_topic($topic_ids)  			WHERE forum_id = ' . $to_forum_id;  		$db->sql_query($sql); +		if (!empty($counter)) +		{ +			// Do only one query per user and not a query per post. +			foreach ($counter as $user_id => $count) +			{ +				$sql = 'UPDATE ' . USERS_TABLE . ' +					SET user_posts = user_posts + ' . (int) $count . ' +					WHERE user_id = ' . (int) $user_id; +				$db->sql_query($sql); +			} +		} +  		sync('topic', 'topic_id', $new_topic_id_list);  		sync('forum', 'forum_id', $to_forum_id); diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 94383b935f..d5a1dbae87 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -250,7 +250,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)  		'U_PM_ACTION'		=> $url . '&mode=compose&f=' . $folder_id . '&p=' . $message_row['msg_id'],  		'S_HAS_ATTACHMENTS'	=> (sizeof($attachments)) ? true : false, -		'S_HAS_MULTIPLE_ATTACHMENTS' => (sizeof($attachments) > 1),  		'S_DISPLAY_NOTICE'	=> $display_notice && $message_row['message_attachment'],  		'S_AUTHOR_DELETED'	=> ($author_id == ANONYMOUS) ? true : false,  		'S_SPECIAL_FOLDER'	=> in_array($folder_id, array(PRIVMSGS_NO_BOX, PRIVMSGS_OUTBOX)), @@ -339,12 +338,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)  	// Display not already displayed Attachments for this post, we already parsed them. ;)  	if (isset($attachments) && sizeof($attachments))  	{ -		$methods = phpbb_gen_download_links('msg_id', $msg_id, $phpbb_root_path, $phpEx); -		foreach ($methods as $method) -		{ -			$template->assign_block_vars('dl_method', $method); -		} -  		foreach ($attachments as $attachment)  		{  			$template->assign_block_vars('attachment', array( diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 517143792a..6a91033dbb 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -13,10 +13,6 @@  $update_start_time = time(); -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -  /**  * @ignore  */ diff --git a/phpBB/install/index.php b/phpBB/install/index.php index d443c537fa..395aff6c7d 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -11,10 +11,6 @@  *  */ -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -  /**#@+  * @ignore  */ diff --git a/phpBB/install/schemas/schema.json b/phpBB/install/schemas/schema.json index 1a9b9b62b7..4e014c77ed 100644 --- a/phpBB/install/schemas/schema.json +++ b/phpBB/install/schemas/schema.json @@ -2711,8 +2711,9 @@                  0              ],              "topic_first_poster_name": [ -                "VCHAR_UNI", -                "" +                "VCHAR_UNI:255", +                "", +                "true_sort"              ],              "topic_first_poster_colour": [                  "VCHAR:6", diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index a58aec43cd..4ce69e0b85 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -191,8 +191,6 @@ $lang = array_merge($lang, array(  	'DISPLAY_MESSAGES'		=> 'Display messages from previous',  	'DISPLAY_POSTS'			=> 'Display posts from previous',  	'DISPLAY_TOPICS'		=> 'Display topics from previous', -	'DOWNLOAD_ALL'			=> 'Download all', -	'DOWNLOAD_ALL_ATTACHMENTS'	=> 'Download all attachments',  	'DOWNLOADED'			=> 'Downloaded',  	'DOWNLOADING_FILE'		=> 'Downloading file',  	'DOWNLOAD_COUNTS'		=> array( diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index edc5941602..f5ba50451a 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -27,7 +27,6 @@ class upload extends \phpbb\avatar\driver\driver  	* Construct a driver object  	*  	* @param \phpbb\config\config $config phpBB configuration -	* @param \phpbb\request\request $request Request object  	* @param string $phpbb_root_path Path to the phpBB root  	* @param string $php_ext PHP file extension  	* @param \phpbb_path_helper $path_helper phpBB path helper diff --git a/phpBB/phpbb/config_php_file.php b/phpBB/phpbb/config_php_file.php index 1a562e470d..7445e7df22 100644 --- a/phpBB/phpbb/config_php_file.php +++ b/phpBB/phpbb/config_php_file.php @@ -71,59 +71,44 @@ class config_php_file  	/**  	* Returns an associative array containing the variables defined by the config file.  	* -	* @return bool|array Return the content of the config file or false if the file does not exists. +	* @return array Return the content of the config file or an empty array if the file does not exists.  	*/  	public function get_all()  	{ -		if (!$this->load_config_file()) -		{ -			return false; -		} +		$this->load_config_file();  		return $this->config_data;  	}  	/** -	* Return the value of a variable defined into the config.php file and false if the variable does not exist. +	* Return the value of a variable defined into the config.php file or null if the variable does not exist.  	*  	* @param string $variable The name of the variable -	* @return mixed +	* @return mixed Value of the variable or null if the variable is not defined.  	*/  	public function get($variable)  	{ -		if (!$this->load_config_file()) -		{ -			return false; -		} +		$this->load_config_file(); -		return isset($this->config_data[$variable]) ? $this->config_data[$variable] : false; +		return isset($this->config_data[$variable]) ? $this->config_data[$variable] : null;  	}  	/**  	* Load the config file and store the information.  	* -	* @return bool True if the file was correctly loaded, false otherwise. +	* @return null  	*/  	protected function load_config_file()  	{ -		if (!$this->config_loaded) +		if (!$this->config_loaded && file_exists($this->config_file))  		{ -			if (file_exists($this->config_file)) -			{ -				$this->defined_vars = get_defined_vars(); +			$this->defined_vars = get_defined_vars(); -				require($this->config_file); -				$this->config_data = array_diff_key(get_defined_vars(), $this->defined_vars); +			require($this->config_file); +			$this->config_data = array_diff_key(get_defined_vars(), $this->defined_vars); -				$this->config_loaded = true; -			} -			else -			{ -				return false; -			} +			$this->config_loaded = true;  		} - -		return true;  	}  	/** diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index da4405d676..8bd537586e 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -570,7 +570,7 @@ class content_visibility  	* Add post to topic and forum statistics  	*  	* @param $data			array	Contains information from the topics table about given topic -	* @param $sql_data		array	Populated with the SQL changes, may be empty at call time +	* @param &$sql_data		array	Populated with the SQL changes, may be empty at call time  	* @return null  	*/  	public function add_post_to_statistic($data, &$sql_data) @@ -591,7 +591,7 @@ class content_visibility  	* Remove post from topic and forum statistics  	*  	* @param $data			array	Contains information from the topics table about given topic -	* @param $sql_data		array	Populated with the SQL changes, may be empty at call time +	* @param &$sql_data		array	Populated with the SQL changes, may be empty at call time  	* @return null  	*/  	public function remove_post_from_statistic($data, &$sql_data) @@ -623,64 +623,29 @@ class content_visibility  	/**  	* Remove topic from forum statistics  	* -	* @param $topic_id		int		The topic to act on -	* @param $forum_id		int		Forum where the topic is found -	* @param $topic_row		array	Contains information from the topic, may be empty at call time -	* @param $sql_data		array	Populated with the SQL changes, may be empty at call time +	* @param $data			array	Post and topic data +	* @param &$sql_data		array	Populated with the SQL changes, may be empty at call time  	* @return null  	*/ -	public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data) +	public function remove_topic_from_statistic($data, &$sql_data)  	{ -		// Do we need to grab some topic informations? -		if (!sizeof($topic_row)) +		if ($data['topic_visibility'] == ITEM_APPROVED)  		{ -			$sql = 'SELECT topic_type, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_visibility -				FROM ' . $this->topics_table . ' -				WHERE topic_id = ' . (int) $topic_id; -			$result = $this->db->sql_query($sql); -			$topic_row = $this->db->sql_fetchrow($result); -			$this->db->sql_freeresult($result); -		} - -		// If this is an edited topic or the first post the topic gets completely disapproved later on... -		$sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_topics_approved = forum_topics_approved - 1'; -		$sql_data[$this->forums_table] .= ', forum_posts_approved = forum_posts_approved - ' . $topic_row['topic_posts_approved']; -		$sql_data[$this->forums_table] .= ', forum_posts_unapproved = forum_posts_unapproved - ' . $topic_row['topic_posts_unapproved']; -		$sql_data[$this->forums_table] .= ', forum_posts_softdeleted = forum_posts_softdeleted - ' . $topic_row['topic_posts_softdeleted']; +			$sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; -		$this->config->increment('num_topics', -1, false); -		$this->config->increment('num_posts', $topic_row['topic_posts_approved'] * (-1), false); - -		// Get user post count information -		$sql = 'SELECT poster_id, COUNT(post_id) AS num_posts -			FROM ' . $this->posts_table . ' -			WHERE topic_id = ' . (int) $topic_id . ' -				AND post_postcount = 1 -				AND post_visibility = ' . ITEM_APPROVED . ' -			GROUP BY poster_id'; -		$result = $this->db->sql_query($sql); - -		$postcounts = array(); -		while ($row = $this->db->sql_fetchrow($result)) +			if ($data['post_postcount']) +			{ +				$sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1'; +			} +		} +		else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)  		{ -			$postcounts[(int) $row['num_posts']][] = (int) $row['poster_id']; +			$sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1';  		} -		$this->db->sql_freeresult($result); - -		// Decrement users post count -		foreach ($postcounts as $num_posts => $poster_ids) +		else if ($data['topic_visibility'] == ITEM_DELETED)  		{ -			$sql = 'UPDATE ' . $this->users_table . ' -				SET user_posts = 0 -				WHERE user_posts < ' . $num_posts . ' -					AND ' . $this->db->sql_in_set('user_id', $poster_ids); -			$this->db->sql_query($sql); - -			$sql = 'UPDATE ' . $this->users_table . ' -				SET user_posts = user_posts - ' . $num_posts . ' -				WHERE user_posts >= ' . $num_posts . ' -					AND ' . $this->db->sql_in_set('user_id', $poster_ids); -			$this->db->sql_query($sql); +			$sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1';  		} +  	}  } diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index efab34b701..948a6a218c 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -41,6 +41,12 @@ class resolver implements ControllerResolverInterface  	protected $template;  	/** +	* Request type cast helper object +	* @var \phpbb\request\type_cast_helper +	*/ +	protected $type_cast_helper; + +	/**  	* phpBB root path  	* @var string  	*/ @@ -59,6 +65,7 @@ class resolver implements ControllerResolverInterface  		$this->user = $user;  		$this->container = $container;  		$this->template = $template; +		$this->type_cast_helper = new \phpbb\request\type_cast_helper();  		$this->phpbb_root_path = $phpbb_root_path;  	} @@ -138,7 +145,16 @@ class resolver implements ControllerResolverInterface  		{  			if (array_key_exists($param->name, $attributes))  			{ -				$arguments[] = $attributes[$param->name]; +				if (is_string($attributes[$param->name])) +				{ +					$value = $attributes[$param->name]; +					$this->type_cast_helper->set_var($value, $attributes[$param->name], 'string', true, false); +					$arguments[] = $value; +				} +				else +				{ +					$arguments[] = $attributes[$param->name]; +				}  			}  			else if ($param->getClass() && $param->getClass()->isInstance($request))  			{ diff --git a/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php new file mode 100644 index 0000000000..527da20590 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php @@ -0,0 +1,44 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class topic_sort_username extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array('\phpbb\db\migration\data\v310\dev'); +	} + +	public function update_schema() +	{ +		return array( +			'change_columns' => array( +				$this->table_prefix . 'topics'	=> array( +					'topic_first_poster_name' => array('VCHAR_UNI:255', '', 'true_sort'), +				), +			), +		); +	} + +	public function revert_schema() +	{ +		return array( +			'change_columns' => array( +				$this->table_prefix . 'topics'	=> array( +					'topic_first_poster_name' => array('VCHAR_UNI:255', ''), +				), +			), +		); +	} +} diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 5d93eb8246..3567570137 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -1816,7 +1816,8 @@ class tools  				$old_return_statements = $this->return_statements;  				$this->return_statements = true; -				$indexes = $this->mssql_get_existing_indexes($table_name, $column_name); +				$indexes = $this->get_existing_indexes($table_name, $column_name); +				$indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true));  				// Drop any indexes  				$recreate_indexes = array(); @@ -2038,7 +2039,7 @@ class tools  			break;  			case 'oracle': -				$statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; +				$statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';  			break;  			case 'sqlite': @@ -2274,10 +2275,23 @@ class tools  	}  	/** +	 * Removes table_name from the index_name if it is at the beginning +	 * +	 * @param $table_name +	 * @param $index_name +	 * @return string +	 */ +	protected function strip_table_name_from_index_name($table_name, $index_name) +	{ +		return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; +	} + +	/**  	* Change column type (not name!)  	*/  	function sql_column_change($table_name, $column_name, $column_data, $inline = false)  	{ +		$original_column_data = $column_data;  		$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);  		$statements = array(); @@ -2289,12 +2303,14 @@ class tools  				$old_return_statements = $this->return_statements;  				$this->return_statements = true; -				$indexes = $this->mssql_get_existing_indexes($table_name, $column_name); +				$indexes = $this->get_existing_indexes($table_name, $column_name); +				$unique_indexes = $this->get_existing_indexes($table_name, $column_name, true);  				// Drop any indexes -				if (!empty($indexes)) +				if (!empty($indexes) || !empty($unique_indexes))  				{ -					foreach ($indexes as $index_name => $index_data) +					$drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); +					foreach ($drop_indexes as $index_name)  					{  						$result = $this->sql_index_drop($table_name, $index_name);  						$statements = array_merge($statements, $result); @@ -2324,6 +2340,16 @@ class tools  					}  				} +				if (!empty($unique_indexes)) +				{ +					// Recreate unique indexes after we changed the column +					foreach ($unique_indexes as $index_name => $index_data) +					{ +						$result = $this->sql_create_unique_index($table_name, $index_name, $index_data); +						$statements = array_merge($statements, $result); +					} +				} +  				$this->return_statements = $old_return_statements;  			break; @@ -2333,7 +2359,69 @@ class tools  			break;  			case 'oracle': -				$statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql']; +				// We need the data here +				$old_return_statements = $this->return_statements; +				$this->return_statements = true; + +				// Get list of existing indexes +				$indexes = $this->get_existing_indexes($table_name, $column_name); +				$unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); + +				// Drop any indexes +				if (!empty($indexes) || !empty($unique_indexes)) +				{ +					$drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); +					foreach ($drop_indexes as $index_name) +					{ +						$result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name)); +						$statements = array_merge($statements, $result); +					} +				} + +				$temp_column_name = 'temp_' . substr(md5($column_name), 0, 25); +				// Add a temporary table with the new type +				$result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data); +				$statements = array_merge($statements, $result); + +				// Copy the data to the new column +				$statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name; + +				// Drop the original column +				$result = $this->sql_column_remove($table_name, $column_name); +				$statements = array_merge($statements, $result); + +				// Recreate the original column with the new type +				$result = $this->sql_column_add($table_name, $column_name, $original_column_data); +				$statements = array_merge($statements, $result); + +				if (!empty($indexes)) +				{ +					// Recreate indexes after we changed the column +					foreach ($indexes as $index_name => $index_data) +					{ +						$result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); +						$statements = array_merge($statements, $result); +					} +				} + +				if (!empty($unique_indexes)) +				{ +					// Recreate unique indexes after we changed the column +					foreach ($unique_indexes as $index_name => $index_data) +					{ +						$result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); +						$statements = array_merge($statements, $result); +					} +				} + +				// Copy the data to the original column +				$statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name; + +				// Drop the temporary column again +				$result = $this->sql_column_remove($table_name, $temp_column_name); +				$statements = array_merge($statements, $result); + +				$this->return_statements = $old_return_statements;  			break;  			case 'postgres': @@ -2517,45 +2605,78 @@ class tools  	*  	* @param string $table_name  	* @param string $column_name +	* @param bool $unique Should we get unique indexes or normal ones  	* @return array		Array with Index name => columns  	*/ -	protected function mssql_get_existing_indexes($table_name, $column_name) +	public function get_existing_indexes($table_name, $column_name, $unique = false)  	{ -		$existing_indexes = array(); -		if ($this->mssql_is_sql_server_2000()) +		switch ($this->sql_layer)  		{ -			// http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx -			// Deprecated in SQL Server 2005 -			$sql = "SELECT DISTINCT ix.name AS phpbb_index_name -				FROM sysindexes ix -				INNER JOIN sysindexkeys ixc -					ON ixc.id = ix.id -						AND ixc.indid = ix.indid -				INNER JOIN syscolumns cols -					ON cols.colid = ixc.colid -						AND cols.id = ix.id -				WHERE ix.id = object_id('{$table_name}') -					AND cols.name = '{$column_name}'"; +			case 'mysql_40': +			case 'mysql_41': +			case 'postgres': +			case 'sqlite': +			case 'sqlite3': +				// Not supported +				throw new \Exception('DBMS is not supported'); +			break;  		} -		else + +		$sql = ''; +		$existing_indexes = array(); + +		switch ($this->sql_layer)  		{ -			$sql = "SELECT DISTINCT ix.name AS phpbb_index_name -				FROM sys.indexes ix -				INNER JOIN sys.index_columns ixc -					ON ixc.object_id = ix.object_id -						AND ixc.index_id = ix.index_id -				INNER JOIN sys.columns cols -					ON cols.column_id = ixc.column_id -						AND cols.object_id = ix.object_id -				WHERE ix.object_id = object_id('{$table_name}') -					AND cols.name = '{$column_name}'"; +			case 'mssql': +			case 'mssqlnative': +				if ($this->mssql_is_sql_server_2000()) +				{ +					// http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx +					// Deprecated in SQL Server 2005 +					$sql = "SELECT DISTINCT ix.name AS phpbb_index_name +					FROM sysindexes ix +					INNER JOIN sysindexkeys ixc +						ON ixc.id = ix.id +							AND ixc.indid = ix.indid +					INNER JOIN syscolumns cols +						ON cols.colid = ixc.colid +							AND cols.id = ix.id +					WHERE ix.id = object_id('{$table_name}') +						AND cols.name = '{$column_name}' +						AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique) ? '1' : '0'; +				} +				else +				{ +					$sql = "SELECT DISTINCT ix.name AS phpbb_index_name +					FROM sys.indexes ix +					INNER JOIN sys.index_columns ixc +						ON ixc.object_id = ix.object_id +							AND ixc.index_id = ix.index_id +					INNER JOIN sys.columns cols +						ON cols.column_id = ixc.column_id +							AND cols.object_id = ix.object_id +					WHERE ix.object_id = object_id('{$table_name}') +						AND cols.name = '{$column_name}' +						AND ix.is_unique = " . ($unique) ? '1' : '0'; +				} +			break; + +			case 'oracle': +				$sql = "SELECT ix.index_name  AS phpbb_index_name, ix.uniqueness AS is_unique +					FROM all_ind_columns ixc, all_indexes ix +					WHERE ix.index_name = ixc.index_name +						AND ixc.table_name = '" . strtoupper($table_name) . "' +						AND ixc.column_name = '" . strtoupper($column_name) . "'"; +			break;  		}  		$result = $this->db->sql_query($sql); -		$existing_indexes = array();  		while ($row = $this->db->sql_fetchrow($result))  		{ -			$existing_indexes[$row['phpbb_index_name']] = array(); +			if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE')) +			{ +				$existing_indexes[$row['phpbb_index_name']] = array(); +			}  		}  		$this->db->sql_freeresult($result); @@ -2564,35 +2685,47 @@ class tools  			return array();  		} -		if ($this->mssql_is_sql_server_2000()) -		{ -			$sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name -				FROM sysindexes ix -				INNER JOIN sysindexkeys ixc -					ON ixc.id = ix.id -						AND ixc.indid = ix.indid -				INNER JOIN syscolumns cols -					ON cols.colid = ixc.colid -						AND cols.id = ix.id -				WHERE ix.id = object_id('{$table_name}') -					AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); -		} -		else +		switch ($this->sql_layer)  		{ -			$sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name -				FROM sys.indexes ix -				INNER JOIN sys.index_columns ixc -					ON ixc.object_id = ix.object_id -						AND ixc.index_id = ix.index_id -				INNER JOIN sys.columns cols -					ON cols.column_id = ixc.column_id -						AND cols.object_id = ix.object_id -				WHERE ix.object_id = object_id('{$table_name}') -					AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); +			case 'mssql': +			case 'mssqlnative': +				if ($this->mssql_is_sql_server_2000()) +				{ +					$sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name +						FROM sysindexes ix +						INNER JOIN sysindexkeys ixc +							ON ixc.id = ix.id +								AND ixc.indid = ix.indid +						INNER JOIN syscolumns cols +							ON cols.colid = ixc.colid +								AND cols.id = ix.id +						WHERE ix.id = object_id('{$table_name}') +							AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); +				} +				else +				{ +					$sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name +						FROM sys.indexes ix +						INNER JOIN sys.index_columns ixc +							ON ixc.object_id = ix.object_id +								AND ixc.index_id = ix.index_id +						INNER JOIN sys.columns cols +							ON cols.column_id = ixc.column_id +								AND cols.object_id = ix.object_id +						WHERE ix.object_id = object_id('{$table_name}') +							AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); +				} +			break; + +			case 'oracle': +				$sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name +					FROM all_ind_columns +					WHERE table_name = '" . strtoupper($table_name) . "' +						AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes)); +			break;  		}  		$result = $this->db->sql_query($sql); -  		while ($row = $this->db->sql_fetchrow($result))  		{  			$existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php index 9c83e8dd73..f3ad7f5f41 100644 --- a/phpBB/phpbb/mimetype/content_guesser.php +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -20,7 +20,7 @@ class content_guesser extends guesser_base  	*/  	public function is_supported()  	{ -		return function_exists('mime_content_type'); +		return function_exists('mime_content_type') && is_callable('mime_content_type');  	}  	/** diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index 0aad19d6bf..22c9076adc 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -81,14 +81,7 @@ class approve_post extends \phpbb\notification\type\post  		$users = array();  		$users[$post['poster_id']] = array(''); -		$auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']); - -		if (empty($auth_read)) -		{ -			return array(); -		} - -		return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( +		return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(  			'item_type'		=> self::$notification_option['id'],  		)));  	} diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index e649f3920e..77e53a0064 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -81,14 +81,7 @@ class approve_topic extends \phpbb\notification\type\topic  		$users = array();  		$users[$post['poster_id']] = array(''); -		$auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']); - -		if (empty($auth_read)) -		{ -			return array(); -		} - -		return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( +		return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(  			'item_type'		=> self::$notification_option['id'],  		)));  	} diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index a11ad76db9..4ead06071e 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -533,4 +533,37 @@ abstract class base implements \phpbb\notification\type\type_interface  			WHERE ' . $where;  		$this->db->sql_query($sql);  	} + +	/** +	 * Get a list of users that are authorised to receive notifications +	 * +	 * @param array $users Array of users that have subscribed to a notification +	 * @param int $forum_id Forum ID of the forum +	 * @param array $options Array of notification options +	 * @param bool $sort Whether the users array should be sorted. Default: false +	 * @return array Array of users that are authorised recipients +	 */ +	protected function get_authorised_recipients($users, $forum_id, $options, $sort = false) +	{ +		if (empty($users)) +		{ +			return array(); +		} + +		$users = array_unique($users); + +		if ($sort) +		{ +			sort($users); +		} + +		$auth_read = $this->auth->acl_get_list($users, 'f_read', $forum_id); + +		if (empty($auth_read)) +		{ +			return array(); +		} + +		return $this->check_user_notification_options($auth_read[$forum_id]['f_read'], $options); +	}  } diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index c83288cfb8..21180b3b53 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -83,21 +83,13 @@ class bookmark extends \phpbb\notification\type\post  		}  		$this->db->sql_freeresult($result); -		if (empty($users)) -		{ -			return array(); -		} -		sort($users); +		$notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true); -		$auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); - -		if (empty($auth_read)) +		if (empty($notify_users))  		{  			return array();  		} -		$notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); -  		// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications  		$update_notifications = array();  		$sql = 'SELECT n.* diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 357176ec35..1eba4a6a88 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -123,23 +123,13 @@ class post extends \phpbb\notification\type\base  		}  		$this->db->sql_freeresult($result); -		if (empty($users)) -		{ -			return array(); -		} +		$notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true); -		$users = array_unique($users); -		sort($users); - -		$auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); - -		if (empty($auth_read)) +		if (empty($notify_users))  		{  			return array();  		} -		$notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); -  		// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications  		$update_notifications = array();  		$sql = 'SELECT n.* diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 6e672e6fbd..5c3c822ec2 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -102,22 +102,7 @@ class quote extends \phpbb\notification\type\post  		}  		$this->db->sql_freeresult($result); -		if (empty($users)) -		{ -			return array(); -		} -		sort($users); - -		$auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); - -		if (empty($auth_read)) -		{ -			return array(); -		} - -		$notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - -		return $notify_users; +		return $this->get_authorised_recipients($users, $post['forum_id'], $options, true);  	}  	/** diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index 289e45bedb..af199fb765 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -111,19 +111,7 @@ class topic extends \phpbb\notification\type\base  		}  		$this->db->sql_freeresult($result); -		if (empty($users)) -		{ -			return array(); -		} - -		$auth_read = $this->auth->acl_get_list($users, 'f_read', $topic['forum_id']); - -		if (empty($auth_read)) -		{ -			return array(); -		} - -		return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], $options); +		return $this->get_authorised_recipients($users, $topic['forum_id'], $options);  	}  	/** diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 649a384418..63efe5f8ae 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -134,6 +134,11 @@ phpbb.markNotifications = function(el, unreadCount) {  	if (!unreadCount) {  		$('#mark_all_notifications').remove();  	} + +	// Update page title +	$('title').text( +		(unreadCount ? '(' + unreadCount + ')' : '') + $('title').text().replace(/(\(([0-9])\))/, '') +	);  };  // This callback finds the post from the delete link, and removes it. diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 62993e9b4e..941541c582 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -113,16 +113,6 @@  			<dl class="attachbox">  				<dt>  					{L_ATTACHMENTS} -					<!-- IF S_HAS_MULTIPLE_ATTACHMENTS --> -						<div class="dl_links"> -							<strong>{L_DOWNLOAD_ALL}{L_COLON}</strong> -							<ul> -							<!-- BEGIN dl_method --> -								<li>[ <a href="{dl_method.LINK}">{dl_method.TYPE}</a> ]</li> -							<!-- END dl_method --> -							</ul> -						</div> -					<!-- ENDIF -->  				</dt>  				<!-- BEGIN attachment -->  					<dd>{attachment.DISPLAY_ATTACHMENT}</dd> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 810c30ed15..ac9c9a362a 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -278,16 +278,6 @@  				<dl class="attachbox">  					<dt>  						{L_ATTACHMENTS} -						<!-- IF postrow.S_MULTIPLE_ATTACHMENTS --> -							<div class="dl_links"> -								<strong>{L_DOWNLOAD_ALL}{L_COLON}</strong> -								<ul> -								<!-- BEGIN dl_method --> -									<li>[ <a href="{postrow.dl_method.LINK}">{postrow.dl_method.TYPE}</a> ]</li> -								<!-- END dl_method --> -								</ul> -							</div> -						<!-- ENDIF -->  					</dt>  					<!-- BEGIN attachment -->  						<dd>{postrow.attachment.DISPLAY_ATTACHMENT}</dd> diff --git a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html index 2a34ebd446..83904bf63d 100644 --- a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html +++ b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html @@ -18,18 +18,6 @@  				<!-- IF U_BUMP_TOPIC --><li class="small-icon icon-bump"><a href="{U_BUMP_TOPIC}" title="{L_BUMP_TOPIC}" data-ajax="true">{L_BUMP_TOPIC}</a></li><!-- ENDIF -->  				<!-- IF U_EMAIL_TOPIC --><li class="small-icon icon-sendemail"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}">{L_EMAIL_TOPIC}</a></li><!-- ENDIF -->  				<!-- IF U_PRINT_TOPIC --><li class="small-icon icon-print"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p">{L_PRINT_TOPIC}</a></li><!-- ENDIF --> -				<!-- IF S_HAS_ATTACHMENTS --> -					<li class="small-icon icon-download"> -						<a class="dropdown-toggle-submenu" href="{U_DOWNLOAD_ALL_ATTACHMENTS}" title="{L_DOWNLOAD_ALL_ATTACHMENTS}">{L_DOWNLOAD_ALL_ATTACHMENTS}</a> -						<ul class="dropdown-submenu hidden"> -							<li> -							<!-- BEGIN dl_method --> -								<a href="{dl_method.LINK}">{dl_method.TYPE}</a><!-- IF not dl_method.S_LAST_ROW --> • <!-- ENDIF -->  -							<!-- END dl_method --> -							</li> -						</ul> -					</li> -				<!-- ENDIF -->  				<!-- EVENT viewtopic_topic_tools_after -->  			</ul>  		</div> diff --git a/phpBB/styles/prosilver/theme/images/icon_print.gif b/phpBB/styles/prosilver/theme/images/icon_print.gifBinary files differ index e464e304ea..e464e304ea 100755..100644 --- a/phpBB/styles/prosilver/theme/images/icon_print.gif +++ b/phpBB/styles/prosilver/theme/images/icon_print.gif diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 50481302e6..8d7ab5323d 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1392,17 +1392,6 @@ if (sizeof($attach_list))  	}  } -$methods = phpbb_gen_download_links('topic_id', $topic_id, $phpbb_root_path, $phpEx); -foreach ($methods as $method) -{ -	$template->assign_block_vars('dl_method', $method); -} - -$template->assign_vars(array( -	'S_HAS_ATTACHMENTS'				=> $topic_data['topic_attachment'], -	'U_DOWNLOAD_ALL_ATTACHMENTS'	=> $methods[0]['LINK'], -)); -  // Instantiate BBCode if need be  if ($bbcode_bitfield !== '')  { @@ -1420,6 +1409,7 @@ $i_total = sizeof($rowset) - 1;  $prev_post_id = '';  $template->assign_vars(array( +	'S_HAS_ATTACHMENTS' => $topic_data['topic_attachment'],  	'S_NUM_POSTS' => sizeof($post_list))  ); @@ -1918,12 +1908,6 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)  				'DISPLAY_ATTACHMENT'	=> $attachment)  			);  		} - -		$methods = phpbb_gen_download_links('post_id', $row['post_id'], $phpbb_root_path, $phpEx); -		foreach ($methods as $method) -		{ -			$template->assign_block_vars('postrow.dl_method', $method); -		}  	}  	$current_row_number = $i; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2856ba02bb..bb4a703cc3 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -31,5 +31,4 @@ require_once 'test_framework/phpbb_test_case_helpers.php';  require_once 'test_framework/phpbb_test_case.php';  require_once 'test_framework/phpbb_database_test_case.php';  require_once 'test_framework/phpbb_database_test_connection_manager.php'; -require_once 'test_framework/phpbb_mink_test_case.php';  require_once 'test_framework/phpbb_functional_test_case.php'; diff --git a/tests/config_php_file_test.php b/tests/config_php_file_test.php index c2e4eb21c7..c319678108 100644 --- a/tests/config_php_file_test.php +++ b/tests/config_php_file_test.php @@ -17,6 +17,7 @@ class phpbb_config_php_file_test extends phpbb_test_case  	{  		$config_php = new \phpbb\config_php_file(dirname( __FILE__ ) . '/fixtures/', 'php');  		$this->assertSame('bar', $config_php->get('foo')); +		$this->assertNull($config_php->get('bar'));  		$this->assertSame(array('foo' => 'bar', 'foo_foo' => 'bar bar'), $config_php->get_all());  	} @@ -25,6 +26,15 @@ class phpbb_config_php_file_test extends phpbb_test_case  		$config_php = new \phpbb\config_php_file(dirname( __FILE__ ) . '/fixtures/', 'php');  		$config_php->set_config_file(dirname( __FILE__ ) . '/fixtures/config_other.php');  		$this->assertSame('foo', $config_php->get('bar')); +		$this->assertNull($config_php->get('foo'));  		$this->assertSame(array('bar' => 'foo', 'bar_bar' => 'foo foo'), $config_php->get_all());  	} + +	public function test_non_existent_file() +	{ +		$config_php = new \phpbb\config_php_file(dirname( __FILE__ ) . '/fixtures/non_existent/', 'php'); +		$this->assertNull($config_php->get('bar')); +		$this->assertNull($config_php->get('foo')); +		$this->assertSame(array(), $config_php->get_all()); +	}  } diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php index aa705c52a5..7f31dd9b28 100644 --- a/tests/content_visibility/delete_post_test.php +++ b/tests/content_visibility/delete_post_test.php @@ -67,6 +67,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array(  				1, 1, 1, @@ -93,6 +96,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array(  				1, 1, 3, @@ -119,6 +125,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 2),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array(  				1, 1, 2, @@ -145,6 +154,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array(  				1, 1, 1, @@ -171,6 +183,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 3),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array(  				1, 1, 3, @@ -197,6 +212,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 2, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 1, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 2),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array( @@ -222,6 +240,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 0, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 0, 'forum_topics_approved' => 0, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 0, 'forum_last_post_id' => 0),  				), +				array( +					array('user_posts' => 3), +				),  			),  			array( @@ -257,6 +278,9 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  				array(  					array('forum_posts_approved' => 0, 'forum_posts_unapproved' => 0, 'forum_posts_softdeleted' => 1, 'forum_topics_approved' => 0, 'forum_topics_unapproved' => 0, 'forum_topics_softdeleted' => 1, 'forum_last_post_id' => 0),  				), +				array( +					array('user_posts' => 3), +				),  			),  		);  	} @@ -264,7 +288,7 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  	/**  	* @dataProvider delete_post_data  	*/ -	public function test_delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason, $expected_posts, $expected_topic, $expected_forum) +	public function test_delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $reason, $expected_posts, $expected_topic, $expected_forum, $expected_user)  	{  		global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx; @@ -313,5 +337,13 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case  		$this->assertEquals($expected_forum, $db->sql_fetchrowset($result));  		$db->sql_freeresult($result); + +		$sql = 'SELECT user_posts +			FROM ' . USERS_TABLE . ' +			WHERE user_id = ' . (int) $data['poster_id']; +		$result = $db->sql_query($sql); + +		$this->assertEquals($expected_user, $db->sql_fetchrowset($result)); +		$db->sql_freeresult($result);  	}  } diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index 6cc2f8ec0f..51f9daacfb 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -288,13 +288,13 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case  		$this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2'));  		// Create index over the column -		$this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); -		$this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_2', array('c_bug_12012_2', 'c_bool'))); -		$this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); +		$this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_2')); +		$this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_2', array('c_bug_12012_2', 'c_bool'))); +		$this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_2')); -		$this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); -		$this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_3', array('c_bug_12012_2'))); -		$this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); +		$this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_3')); +		$this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_3', array('c_bug_12012_2'))); +		$this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_3'));  		// Remove the column  		$this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); diff --git a/tests/functional/download_test.php b/tests/functional/download_test.php index 6a6df14c81..4e4995c21e 100644 --- a/tests/functional/download_test.php +++ b/tests/functional/download_test.php @@ -80,20 +80,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case  			'attachments' => true,  		)); -		// Download topic archive as guest -		$crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); - -		// Download post archive as guest -		$crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); -  		// Download attachment as guest  		$crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false);  		self::assert_response_status_code(200); @@ -147,18 +133,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case  		));  		$this->add_lang('viewtopic'); -		// Download topic archive as guest: still works -		$crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); - -		// No download post archive as guest -		$crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); -		self::assert_response_html(404); -		$this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); -  		// No download attachment as guest  		$crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false);  		self::assert_response_html(404); @@ -167,20 +141,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case  		// Login as admin and try again, should work now.  		$this->login(); -		// Download topic archive as admin -		$crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); - -		// Download post archive as admin -		$crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); -  		// Download attachment as admin  		$crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false);  		self::assert_response_status_code(200); @@ -235,16 +195,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case  		));  		$this->add_lang('viewtopic'); -		// Download topic archive as guest: still works -		$crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); -		self::assert_response_html(404); -		$this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); - -		// No download post archive as guest -		$crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); -		self::assert_response_html(404); -		$this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); -  		// No download attachment as guest  		$crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false);  		self::assert_response_html(404); @@ -253,20 +203,6 @@ class phpbb_functional_download_test extends phpbb_functional_test_case  		// Login as admin and try again, should work now.  		$this->login(); -		// Download topic archive as admin -		$crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); - -		// Download post archive as admin -		$crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); -		self::assert_response_status_code(200); -		$content = self::$client->getResponse()->getContent(); -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		self::assertEquals('application/zip', $finfo->buffer($content)); -  		// Download attachment as admin  		$crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false);  		self::assert_response_status_code(200); diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index 29036c821e..e87953367f 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -42,8 +42,6 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case  			unlink($fileinfo->getPathname());  		} - -		parent::tearDown();  	}  	private function upload_file($filename, $mimetype) diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index ef39e1d71b..6ece150b23 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -45,8 +45,6 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case  		global $config, $user;  		$user = null;  		$config = array(); - -		parent::tearDown();  	}  	public function test_invalid_extension() diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php index c95efc5b2e..64fa19557f 100644 --- a/tests/functional/forgot_password_test.php +++ b/tests/functional/forgot_password_test.php @@ -57,7 +57,5 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case  			'config[allow_password_reset]'	=> 1,  		));  		$crawler = self::submit($form); - -		parent::tearDown();  	}  } diff --git a/tests/functional/plupload_test.php b/tests/functional/plupload_test.php index d9faec035c..ee71597ffc 100644 --- a/tests/functional/plupload_test.php +++ b/tests/functional/plupload_test.php @@ -57,8 +57,6 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case  			unlink($fileinfo->getPathname());  		} - -		parent::tearDown();  	}  	public function get_urls() diff --git a/tests/functions/insert_config_array_test.php b/tests/functions/insert_config_array_test.php new file mode 100644 index 0000000000..bfcb05862e --- /dev/null +++ b/tests/functions/insert_config_array_test.php @@ -0,0 +1,142 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class phpbb_functions_insert_config_array_test extends phpbb_test_case +{ +	public function config_display_vars() +	{ +		return array( +			'legend1'		=> '', +			'acp_config_1'	=> array(), +			'acp_config_2'	=> array(), +			'acp_config_3'	=> array(), +			'acp_config_4'	=> array(), +			'acp_config_5'	=> array(), +		); +	} + +	public function insert_config_array_data() +	{ +		return array( +			array( // Add a new config after 1st array item +				array('new_config_1' => array()), +				array('after' => 'legend1'), +				array( +					'legend1'		=> '', +					'new_config_1'	=> array(), +					'acp_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'acp_config_5'	=> array(), +				), +			), +			array( // Add a new config after last array item +				array('new_config_1' => array()), +				array('after' => 'acp_config_5'), +				array( +					'legend1'		=> '', +					'acp_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'acp_config_5'	=> array(), +					'new_config_1'	=> array(), +				), +			), +			array( // Add a new config before 2nd array item +				array('new_config_1' => array()), +				array('before' => 'acp_config_1'), +				array( +					'legend1'		=> '', +					'new_config_1'	=> array(), +					'acp_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'acp_config_5'	=> array(), +				), +			), +			array( // Add a new config before last config item +				array('new_config_1' => array()), +				array('before' => 'acp_config_5'), +				array( +					'legend1'		=> '', +					'acp_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'new_config_1'	=> array(), +					'acp_config_5'	=> array(), +				), +			), +			array( // When an array key does not exist +				array('new_config_1' => array()), +				array('after' => 'foobar'), +				array( +					'legend1'		=> '', +					'acp_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'acp_config_5'	=> array(), +				), +			), +			array( // When after|before is not used correctly (defaults to after) +				array('new_config_1' => array()), +				array('foobar' => 'acp_config_1'), +				array( +					'legend1'		=> '', +					'acp_config_1'	=> array(), +					'new_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'acp_config_5'	=> array(), +				), +			), +			array( // Add a new config set after the last array item +				array( +					'legend2' => array(), +					'new_config_1' => array(), +					'new_config_2' => array(), +					'new_config_3' => array(), +				), +				array('after' => 'acp_config_5'), +				array( +					'legend1'		=> '', +					'acp_config_1'	=> array(), +					'acp_config_2'	=> array(), +					'acp_config_3'	=> array(), +					'acp_config_4'	=> array(), +					'acp_config_5'	=> array(), +					'legend2' => array(), +					'new_config_1' => array(), +					'new_config_2' => array(), +					'new_config_3' => array(), +				), +			), +		); +	} + +	/** +	* @dataProvider insert_config_array_data +	*/ +	public function test_insert_config_array($new_config, $position, $expected) +	{ +		$config_array = $this->config_display_vars(); +		$new_config_array = phpbb_insert_config_array($config_array, $new_config, $position); + +		$this->assertSame($expected, $new_config_array); +	} +} diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 9bb4d69bf4..80e6293ff9 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -11,12 +11,14 @@  *  */  use Symfony\Component\BrowserKit\CookieJar; -use Behat\Mink\Driver\Goutte\Client; -use Behat\Mink\Driver\GoutteDriver; -class phpbb_functional_test_case extends phpbb_mink_test_case +require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; + +class phpbb_functional_test_case extends phpbb_test_case  { +	static protected $client;  	static protected $cookieJar; +	static protected $root_url;  	protected $cache = null;  	protected $db = null; @@ -34,6 +36,7 @@ class phpbb_functional_test_case extends phpbb_mink_test_case  	*/  	protected $lang = array(); +	static protected $config = array();  	static protected $already_installed = false;  	static public function setUpBeforeClass() @@ -43,24 +46,6 @@ class phpbb_functional_test_case extends phpbb_mink_test_case  		self::$config = phpbb_test_case_helpers::get_test_config();  		self::$root_url = self::$config['phpbb_functional_url']; -		self::$cookieJar = new CookieJar; -		self::$client = new Client(array(), null, self::$cookieJar); - -		$client_options = array( -			Guzzle\Http\Client::DISABLE_REDIRECTS	=> true, -			'curl.options'	=> array( -				CURLOPT_TIMEOUT	=> 120, -			), -		); - -		self::$client->setClient(new Guzzle\Http\Client('', $client_options)); - -		// Reset the curl handle because it is 0 at this point and not a valid -		// resource -		self::$client->getClient()->getCurlMulti()->reset(true); - -		self::$driver = new GoutteDriver(self::$client); -  		// Important: this is used both for installation and by  		// test cases for querying the tables.  		// Therefore table prefix must be set before a board is @@ -93,6 +78,12 @@ class phpbb_functional_test_case extends phpbb_mink_test_case  		$this->bootstrap(); +		self::$cookieJar = new CookieJar; +		self::$client = new Goutte\Client(array(), null, self::$cookieJar); +		// Reset the curl handle because it is 0 at this point and not a valid +		// resource +		self::$client->getClient()->getCurlMulti()->reset(true); +  		// Clear the language array so that things  		// that were added in other tests are gone  		$this->lang = array(); @@ -119,14 +110,13 @@ class phpbb_functional_test_case extends phpbb_mink_test_case  	protected function tearDown()  	{ +		parent::tearDown(); +  		if ($this->db instanceof \phpbb\db\driver\driver_interface)  		{  			// Close the database connections again this test  			$this->db->sql_close();  		} - -		self::$cookieJar->clear(); -		parent::tearDown();  	}  	/** @@ -266,6 +256,144 @@ class phpbb_functional_test_case extends phpbb_mink_test_case  		return $extension_manager;  	} +	static protected function install_board() +	{ +		global $phpbb_root_path, $phpEx; + +		self::recreate_database(self::$config); + +		$config_file = $phpbb_root_path . "config.$phpEx"; +		$config_file_dev = $phpbb_root_path . "config_dev.$phpEx"; +		$config_file_test = $phpbb_root_path . "config_test.$phpEx"; + +		if (file_exists($config_file)) +		{ +			if (!file_exists($config_file_dev)) +			{ +				rename($config_file, $config_file_dev); +			} +			else +			{ +				unlink($config_file); +			} +		} + +		self::$cookieJar = new CookieJar; +		self::$client = new Goutte\Client(array(), null, self::$cookieJar); +		// Set client manually so we can increase the cURL timeout +		self::$client->setClient(new Guzzle\Http\Client('', array( +			Guzzle\Http\Client::DISABLE_REDIRECTS	=> true, +			'curl.options'	=> array( +				CURLOPT_TIMEOUT	=> 120, +			), +		))); + +		// Reset the curl handle because it is 0 at this point and not a valid +		// resource +		self::$client->getClient()->getCurlMulti()->reset(true); + +		$parseURL = parse_url(self::$config['phpbb_functional_url']); + +		$crawler = self::request('GET', 'install/index.php?mode=install'); +		self::assertContains('Welcome to Installation', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(); + +		// install/index.php?mode=install&sub=requirements +		$crawler = self::submit($form); +		self::assertContains('Installation compatibility', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(); + +		// install/index.php?mode=install&sub=database +		$crawler = self::submit($form); +		self::assertContains('Database configuration', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(array( +			// Installer uses 3.0-style dbms name +			'dbms'			=> str_replace('phpbb\db\driver\\', '',  self::$config['dbms']), +			'dbhost'		=> self::$config['dbhost'], +			'dbport'		=> self::$config['dbport'], +			'dbname'		=> self::$config['dbname'], +			'dbuser'		=> self::$config['dbuser'], +			'dbpasswd'		=> self::$config['dbpasswd'], +			'table_prefix'	=> self::$config['table_prefix'], +		)); + +		// install/index.php?mode=install&sub=database +		$crawler = self::submit($form); +		self::assertContains('Successful connection', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(); + +		// install/index.php?mode=install&sub=administrator +		$crawler = self::submit($form); +		self::assertContains('Administrator configuration', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(array( +			'default_lang'	=> 'en', +			'admin_name'	=> 'admin', +			'admin_pass1'	=> 'adminadmin', +			'admin_pass2'	=> 'adminadmin', +			'board_email'	=> 'nobody@example.com', +		)); + +		// install/index.php?mode=install&sub=administrator +		$crawler = self::submit($form); +		self::assertContains('Tests passed', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(); + +		// We have to skip install/index.php?mode=install&sub=config_file +		// because that step will create a config.php file if phpBB has the +		// permission to do so. We have to create the config file on our own +		// in order to get the DEBUG constants defined. +		$config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); +		$config_created = file_put_contents($config_file, $config_php_data) !== false; +		if (!$config_created) +		{ +			self::markTestSkipped("Could not write $config_file file."); +		} + +		// We also have to create a install lock that is normally created by +		// the installer. The file will be removed by the final step of the +		// installer. +		$install_lock_file = $phpbb_root_path . 'cache/install_lock'; +		$lock_created = file_put_contents($install_lock_file, '') !== false; +		if (!$lock_created) +		{ +			self::markTestSkipped("Could not create $lock_created file."); +		} +		@chmod($install_lock_file, 0666); + +		// install/index.php?mode=install&sub=advanced +		$form_data = $form->getValues(); +		unset($form_data['submit']); + +		$crawler = self::request('POST', 'install/index.php?mode=install&sub=advanced', $form_data); +		self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(array( +			'email_enable'		=> true, +			'smtp_delivery'		=> true, +			'smtp_host'			=> 'nxdomain.phpbb.com', +			'smtp_auth'			=> 'PLAIN', +			'smtp_user'			=> 'nxuser', +			'smtp_pass'			=> 'nxpass', +			'cookie_secure'		=> false, +			'force_server_vars'	=> false, +			'server_protocol'	=> $parseURL['scheme'] . '://', +			'server_name'		=> 'localhost', +			'server_port'		=> isset($parseURL['port']) ? (int) $parseURL['port'] : 80, +			'script_path'		=> $parseURL['path'], +		)); + +		// install/index.php?mode=install&sub=create_table +		$crawler = self::submit($form); +		self::assertContains('The database tables used by phpBB', $crawler->filter('#main')->text()); +		self::assertContains('have been created and populated with some initial data.', $crawler->filter('#main')->text()); +		$form = $crawler->selectButton('submit')->form(); + +		// install/index.php?mode=install&sub=final +		$crawler = self::submit($form); +		self::assertContains('You have successfully installed', $crawler->text()); + +		copy($config_file, $config_file_test); +	} +  	public function install_ext($extension)  	{  		$this->login(); @@ -284,6 +412,12 @@ class phpbb_functional_test_case extends phpbb_mink_test_case  		$this->logout();  	} +	static private function recreate_database($config) +	{ +		$db_conn_mgr = new phpbb_database_test_connection_manager($config); +		$db_conn_mgr->recreate_db(); +	} +  	/**  	* Creates a new style  	* diff --git a/tests/test_framework/phpbb_mink_test_case.php b/tests/test_framework/phpbb_mink_test_case.php deleted file mode 100644 index ba480e35fb..0000000000 --- a/tests/test_framework/phpbb_mink_test_case.php +++ /dev/null @@ -1,183 +0,0 @@ -<?php -/** -* -* This file is part of the phpBB Forum Software package. -* -* @copyright (c) phpBB Limited <https://www.phpbb.com> -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ -use \Behat\Mink\Session; - -require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; - -abstract class phpbb_mink_test_case extends phpbb_test_case -{ -	static protected $driver; -	static protected $client; -	static protected $session; -	static protected $config = array(); -	static protected $root_url; - -	public function __construct($name = null, array $data = array(), $dataName = '') -	{ -		parent::__construct($name, $data, $dataName); - -		$this->backupStaticAttributesBlacklist += array( -			'phpbb_mink_test_case' => array('config', 'already_installed'), -		); -	} - -	static public function setUpBeforeClass() -	{ -		parent::setUpBeforeClass(); -	} - -	public function setUp() -	{ -		parent::setUp(); - -		if (!self::$driver) -		{ -			self::markTestSkipped('Mink driver not initialized.'); -		} - -		if (!self::$session) -		{ -			self::$session = new Session(self::$driver); -		} -	} - -	static protected function recreate_database($config) -	{ -		$db_conn_mgr = new phpbb_database_test_connection_manager($config); -		$db_conn_mgr->recreate_db(); -	} - -	protected function tearDown() -	{ -		self::$session->reset(); -		parent::tearDown(); -	} - -	static protected function visit($path) -	{ -		self::$session->visit(self::$root_url . $path); -		return self::$session->getPage(); -	} - -	static protected function click_submit($submit_button_id = 'submit') -	{ -		self::$session->getPage()->findById($submit_button_id)->click(); -		return self::$session->getPage(); -	} - -	static protected function install_board() -	{ -		global $phpbb_root_path, $phpEx; - -		self::recreate_database(self::$config); -		self::$session = new Session(self::$driver); - -		$config_file = $phpbb_root_path . "config.$phpEx"; -		$config_file_dev = $phpbb_root_path . "config_dev.$phpEx"; -		$config_file_test = $phpbb_root_path . "config_test.$phpEx"; - -		if (file_exists($config_file)) -		{ -			if (!file_exists($config_file_dev)) -			{ -				rename($config_file, $config_file_dev); -			} -			else -			{ -				unlink($config_file); -			} -		} - -		$parseURL = parse_url(self::$config['phpbb_functional_url']); - -		$page = self::visit('install/index.php?mode=install'); -		self::assertContains('Welcome to Installation', $page->findById('main')->getText()); - -		// install/index.php?mode=install&sub=requirements -		$page = self::click_submit(); -		self::assertContains('Installation compatibility', $page->findById('main')->getText()); - -		// install/index.php?mode=install&sub=database -		$page = self::click_submit(); -		self::assertContains('Database configuration', $page->findById('main')->getText()); - -		$page->findById('dbms')->setValue(str_replace('phpbb\db\driver\\', '',  self::$config['dbms'])); -		$page->findById('dbhost')->setValue(self::$config['dbhost']); -		$page->findById('dbport')->setValue(self::$config['dbport']); -		$page->findById('dbname')->setValue(self::$config['dbname']); -		$page->findById('dbuser')->setValue(self::$config['dbuser']); -		$page->findById('dbpasswd')->setValue(self::$config['dbpasswd']); -		$page->findById('table_prefix')->setValue(self::$config['table_prefix']); - -		// install/index.php?mode=install&sub=database -		$page = self::click_submit(); -		self::assertContains('Successful connection', $page->findById('main')->getText()); - -		// install/index.php?mode=install&sub=administrator -		$page = self::click_submit(); -		self::assertContains('Administrator configuration', $page->findById('main')->getText()); - -		$page->findById('admin_name')->setValue('admin'); -		$page->findById('admin_pass1')->setValue('adminadmin'); -		$page->findById('admin_pass2')->setValue('adminadmin'); -		$page->findById('board_email')->setValue('nobody@example.com'); - -		// install/index.php?mode=install&sub=administrator -		$page = self::click_submit(); -		self::assertContains('Tests passed', $page->findById('main')->getText()); - -		// install/index.php?mode=install&sub=config_file -		$page = self::click_submit(); - -		// Installer has created a config.php file, we will overwrite it with a -		// config file of our own in order to get the DEBUG constants defined -		$config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); -		$config_created = file_put_contents($config_file, $config_php_data) !== false; -		if (!$config_created) -		{ -			self::markTestSkipped("Could not write $config_file file."); -		} - -		if (strpos($page->findById('main')->getText(), 'The configuration file has been written') === false) -		{ -			$page = self::click_submit('dldone'); -		} -		self::assertContains('The configuration file has been written', $page->findById('main')->getText()); - -		// install/index.php?mode=install&sub=advanced -		$page = self::click_submit(); -		self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', $page->findById('main')->getText()); - -		$page->findById('smtp_delivery')->setValue('1'); -		$page->findById('smtp_host')->setValue('nxdomain.phpbb.com'); -		$page->findById('smtp_user')->setValue('nxuser'); -		$page->findById('smtp_pass')->setValue('nxpass'); -		$page->findById('server_protocol')->setValue($parseURL['scheme'] . '://'); -		$page->findById('server_name')->setValue('localhost'); -		$page->findById('server_port')->setValue(isset($parseURL['port']) ? $parseURL['port'] : 80); -		$page->findById('script_path')->setValue($parseURL['path']); - -		// install/index.php?mode=install&sub=create_table -		$page = self::click_submit(); -		self::assertContains('The database tables used by phpBB', $page->findById('main')->getText()); -		self::assertContains('have been created and populated with some initial data.', $page->findById('main')->getText()); - -		// install/index.php?mode=install&sub=final -		$page = self::click_submit(); -		self::assertContains('You have successfully installed', $page->getText()); - -		copy($config_file, $config_file_test); - -		self::$session->stop(); -	} -} diff --git a/travis/check-executable-files.sh b/travis/check-executable-files.sh new file mode 100755 index 0000000000..4d420add1c --- /dev/null +++ b/travis/check-executable-files.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited <https://www.phpbb.com> +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e + +DB=$1 +TRAVIS_PHP_VERSION=$2 +root="$3" +path="${root}phpBB/" + +if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ] +then +	# Check the permissions of the files + +	# The following variables MUST NOT contain any wildcard +	# Directories to skip +	directories_skipped="-path ${path}develop -o -path ${path}vendor" + +	# Files to skip +	files_skipped="-false" + +	# Files which have to be executable +	executable_files="-path ${path}bin/*" + +	incorrect_files=$( 								\ +		find ${path}								\ +			'('										\ +				'('									\ +					${directories_skipped}			\ +				')'									\ +				-a -type d -prune -a -type f		\ +			')' -o 									\ +			'('										\ +				-type f -a							\ +				-not '('							\ +					${files_skipped}				\ +				')' -a								\ +				'('									\ +					'('								\ +						'('							\ +							${executable_files}		\ +						')' -a						\ +						-not -perm +100				\ +					')' -o							\ +					'('								\ +						-not '('					\ +							${executable_files}		\ +						')' -a						\ +						-perm +111					\ +					')'								\ +				')'									\ +			')'										\ +		) + +	if [ "${incorrect_files}" != '' ] +	then +		echo "The following files do not have proper permissions:"; +		ls -la ${incorrect_files} +		exit 1; +	fi +fi diff --git a/travis/check-sami-parse-errors.sh b/travis/check-sami-parse-errors.sh new file mode 100755 index 0000000000..847c54a61a --- /dev/null +++ b/travis/check-sami-parse-errors.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited <https://www.phpbb.com> +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e + +DB=$1 +TRAVIS_PHP_VERSION=$2 + +if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ] +then +	# Workarounds for +	# https://github.com/fabpot/Sami/issues/116 +	# and +	# https://github.com/fabpot/Sami/issues/117 +	errors=$( +		unbuffer phpBB/vendor/bin/sami.php parse travis/sami.conf.php -v | \ +		sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | \ +		grep "ERROR: " | \ +		tee /dev/tty | \ +		wc -l +	) +	if [ "$errors" != "0" ] +	then +		exit 1 +	fi +fi diff --git a/travis/sami.conf.php b/travis/sami.conf.php new file mode 100644 index 0000000000..8e7cfa42e9 --- /dev/null +++ b/travis/sami.conf.php @@ -0,0 +1,19 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +require __DIR__ . '/../build/' . basename(__FILE__); + +// Removing the versions array key will make Sami use the current branch. +unset($config['versions']); + +return new Sami\Sami($iterator, $config); diff --git a/travis/setup-php-extensions.sh b/travis/setup-php-extensions.sh index 3655d6e952..c0defe44ef 100755 --- a/travis/setup-php-extensions.sh +++ b/travis/setup-php-extensions.sh @@ -42,12 +42,6 @@ function install_php_extension  php_ini_file=$(find_php_ini) -# disable broken opcache on PHP 5.5.7 and 5.5.8 -if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.9', '<');"` == "1" ] -then -	sed -i '/opcache.so/d' "$php_ini_file" -fi -  # apc  if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.0-dev', '<');"` == "1" ]  then diff --git a/travis/setup-phpbb.sh b/travis/setup-phpbb.sh index f065faf8e2..d829772196 100755 --- a/travis/setup-phpbb.sh +++ b/travis/setup-phpbb.sh @@ -17,6 +17,7 @@ TRAVIS_PHP_VERSION=$2  if [ "$TRAVIS_PHP_VERSION" == "5.3.3" -a "$DB" == "mysqli" ]  then  	travis/setup-exiftool.sh +	travis/setup-unbuffer.sh  fi  if [ "$DB" == "mariadb" ] diff --git a/travis/setup-unbuffer.sh b/travis/setup-unbuffer.sh new file mode 100755 index 0000000000..4423d1b8b6 --- /dev/null +++ b/travis/setup-unbuffer.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited <https://www.phpbb.com> +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e + +sudo apt-get update +sudo apt-get install -y expect-dev diff --git a/travis/setup-webserver.sh b/travis/setup-webserver.sh index ea1929a5b0..ab045431cc 100755 --- a/travis/setup-webserver.sh +++ b/travis/setup-webserver.sh @@ -72,8 +72,11 @@ echo "  		index	index.php index.html;  		location ~ \.php { -			fastcgi_pass	unix:$APP_SOCK; -			include			fastcgi_params; +			include							fastcgi_params; +			fastcgi_split_path_info			^(.+\.php)(/.*)$; +			fastcgi_param PATH_INFO			\$fastcgi_path_info; +			fastcgi_param SCRIPT_FILENAME	\$document_root\$fastcgi_script_name; +			fastcgi_pass					unix:$APP_SOCK;  		}  	}  " | sudo tee $NGINX_CONF > /dev/null | 
