diff options
Diffstat (limited to 'phpBB/phpbb')
26 files changed, 1602 insertions, 76 deletions
diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 34b894c2a7..c4344ee6e8 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -81,7 +81,8 @@ class gravatar extends \phpbb\avatar\driver\driver array( 'email' => array( array('string', false, 6, 60), - array('email')) + array('email'), + ), ) ); diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php index 00e519e3f2..f3acf7cb2c 100644 --- a/phpBB/phpbb/avatar/driver/local.php +++ b/phpBB/phpbb/avatar/driver/local.php @@ -36,7 +36,7 @@ class local extends \phpbb\avatar\driver\driver public function prepare_form($request, $template, $user, $row, &$error) { $avatar_list = $this->get_avatar_list($user); - $category = $request->variable('avatar_local_cat', ''); + $category = $request->variable('avatar_local_cat', key($avatar_list)); foreach ($avatar_list as $cat => $null) { @@ -131,7 +131,7 @@ class local extends \phpbb\avatar\driver\driver } return array( - 'avatar' => ($category != $user->lang['MAIN']) ? $category . '/' . $file : $file, + 'avatar' => ($category != $user->lang['NO_AVATAR_CATEGORY']) ? $category . '/' . $file : $file, 'avatar_width' => $avatar_list[$category][urldecode($file)]['width'], 'avatar_height' => $avatar_list[$category][urldecode($file)]['height'], ); @@ -179,9 +179,9 @@ class local extends \phpbb\avatar\driver\driver { $dims = array(0, 0); } - $cat = ($path == $file_path) ? $user->lang['MAIN'] : str_replace("$path/", '', $file_path); + $cat = ($path == $file_path) ? $user->lang['NO_AVATAR_CATEGORY'] : str_replace("$path/", '', $file_path); $avatar_list[$cat][$image] = array( - 'file' => ($cat != $user->lang['MAIN']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image), + 'file' => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image), 'filename' => rawurlencode($image), 'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $image))), 'width' => $dims[0], diff --git a/phpBB/phpbb/config/config.php b/phpBB/phpbb/config/config.php index 8cbe1e1e2d..aaad333006 100644 --- a/phpBB/phpbb/config/config.php +++ b/phpBB/phpbb/config/config.php @@ -37,7 +37,7 @@ class config implements \ArrayAccess, \IteratorAggregate, \Countable /** * Retrieves an ArrayIterator over the configuration values. * - * @return ArrayIterator An iterator over all config data + * @return \ArrayIterator An iterator over all config data */ public function getIterator() { diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php index da2bfbb49a..b1f0635913 100644 --- a/phpBB/phpbb/console/application.php +++ b/phpBB/phpbb/console/application.php @@ -13,15 +13,93 @@ namespace phpbb\console; +use Symfony\Component\Console\Shell; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\TaggedContainerInterface; class application extends \Symfony\Component\Console\Application { - function register_container_commands(TaggedContainerInterface $container, $tag = 'console.command') + /** + * @var bool Indicates whether or not we are in a shell + */ + protected $in_shell = false; + + /** + * @var \phpbb\user User object + */ + protected $user; + + /** + * @param string $name The name of the application + * @param string $version The version of the application + * @param \phpbb\user $user The user which runs the application (used for translation) + */ + public function __construct($name, $version, \phpbb\user $user) + { + parent::__construct($name, $version); + + $this->user = $user; + } + + /** + * Gets the help message. + * + * It's a hack of the default help message to display the --shell + * option only for the application and not for all the commands. + * + * @return string A help message. + */ + public function getHelp() + { + // If we are already in a shell + // we do not want to have the --shell option available + if ($this->in_shell) + { + return parent::getHelp(); + } + + $this->getDefinition()->addOption(new InputOption( + '--shell', + '-s', + InputOption::VALUE_NONE, + $this->user->lang('CLI_DESCRIPTION_OPTION_SHELL') + )); + + return parent::getHelp(); + } + + /** + * Register a set of commands from the container + * + * @param TaggedContainerInterface $container The container + * @param string $tag The tag used to register the commands + */ + public function register_container_commands(TaggedContainerInterface $container, $tag = 'console.command') { foreach($container->findTaggedServiceIds($tag) as $id => $void) { $this->add($container->get($id)); } } + + /** + * {@inheritdoc} + */ + public function doRun(InputInterface $input, OutputInterface $output) + { + // Run a shell if the --shell (or -s) option is set and if no command name is specified + // Also, we do not want to have the --shell option available if we are already in a shell + if (!$this->in_shell && $this->getCommandName($input) === null && $input->hasParameterOption(array('--shell', '-s'))) + { + $shell = new Shell($this); + $this->in_shell = true; + $shell->run(); + + return 0; + } + + return parent::doRun($input, $output); + } } diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php index 1e2adaeb4d..50953185a4 100644 --- a/phpBB/phpbb/console/command/cache/purge.php +++ b/phpBB/phpbb/console/command/cache/purge.php @@ -43,7 +43,6 @@ class purge extends \phpbb\console\command\command $this->log = $log; $this->user = $user; $this->config = $config; - $this->user->add_lang(array('acp/common')); parent::__construct(); } diff --git a/phpBB/phpbb/console/command/cron/cron_list.php b/phpBB/phpbb/console/command/cron/cron_list.php new file mode 100644 index 0000000000..9db6a23947 --- /dev/null +++ b/phpBB/phpbb/console/command/cron/cron_list.php @@ -0,0 +1,90 @@ +<?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\console\command\cron; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class cron_list extends \phpbb\console\command\command +{ + /** @var \phpbb\cron\manager */ + protected $cron_manager; + + /** @var \phpbb\user */ + protected $user; + + public function __construct(\phpbb\cron\manager $cron_manager, \phpbb\user $user) + { + $this->cron_manager = $cron_manager; + $this->user = $user; + parent::__construct(); + } + + protected function configure() + { + $this + ->setName('cron:list') + ->setDescription($this->user->lang('CLI_DESCRIPTION_CRON_LIST')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $tasks = $this->cron_manager->get_tasks(); + + if (empty($tasks)) + { + $output->writeln($this->user->lang('CRON_NO_TASKS')); + return; + } + + $ready_tasks = array(); + $not_ready_tasks = array(); + foreach ($tasks as $task) + { + if ($task->is_ready()) + { + $ready_tasks[] = $task; + } + else + { + $not_ready_tasks[] = $task; + } + } + + if (!empty($ready_tasks)) + { + $output->writeln('<info>' . $this->user->lang('TASKS_READY') . '</info>'); + $this->print_tasks_names($ready_tasks, $output); + } + + if (!empty($ready_tasks) && !empty($not_ready_tasks)) + { + $output->writeln(''); + } + + if (!empty($not_ready_tasks)) + { + $output->writeln('<info>' . $this->user->lang('TASKS_NOT_READY') . '</info>'); + $this->print_tasks_names($not_ready_tasks, $output); + } + } + + protected function print_tasks_names(array $tasks, OutputInterface $output) + { + foreach ($tasks as $task) + { + $output->writeln($task->get_name()); + } + } +} diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php new file mode 100644 index 0000000000..1029a2e085 --- /dev/null +++ b/phpBB/phpbb/console/command/cron/run.php @@ -0,0 +1,176 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited +* @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\console\command\cron; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class run extends \phpbb\console\command\command +{ + /** @var \phpbb\cron\manager */ + protected $cron_manager; + + /** @var \phpbb\lock\db */ + protected $lock_db; + + /** @var \phpbb\user */ + protected $user; + + /** + * Construct method + * + * @param \phpbb\cron\manager $cron_manager The cron manager containing + * the cron tasks to be executed. + * @param \phpbb\lock\db $lock_db The lock for accessing database. + * @param \phobb\user $user The user object (used to get language information) + */ + public function __construct(\phpbb\cron\manager $cron_manager, \phpbb\lock\db $lock_db, \phpbb\user $user) + { + $this->cron_manager = $cron_manager; + $this->lock_db = $lock_db; + $this->user = $user; + parent::__construct(); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('cron:run') + ->setDescription($this->user->lang('CLI_DESCRIPTION_CRON_RUN')) + ->addArgument('name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_CRON_RUN_ARGUMENT_1')) + ; + } + + /** + * Executes the command cron:run. + * + * Tries to acquire the cron lock, then if no argument has been given runs all ready cron tasks. + * If the cron lock can not be obtained, an error message is printed + * and the exit status is set to 1. + * If the verbose option is specified, each start of a task is printed. + * Otherwise there is no output. + * If an argument is given to the command, only the task whose name matches the + * argument will be started. If verbose option is specified, + * an info message containing the name of the task is printed. + * If no task matches the argument given, an error message is printed + * and the exit status is set to 2. + * + * @param InputInterface $input The input stream used to get the argument and verboe option. + * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. + * + * @return int 0 if all is ok, 1 if a lock error occured and 2 if no task matching the argument was found. + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if ($this->lock_db->acquire()) + { + $task_name = $input->getArgument('name'); + if ($task_name) + { + $exit_status = $this->run_one($input, $output, $task_name); + } + else + { + $exit_status = $this->run_all($input, $output); + } + + $this->lock_db->release(); + return $exit_status; + } + else + { + $output->writeln('<error>' . $this->user->lang('CRON_LOCK_ERROR') . '</error>'); + return 1; + } + } + + /* + * Executes all ready cron tasks. + * + * If verbose mode is set, an info message will be printed if there is no task to + * be run, or else for each starting task. + * + * @see execute + * @param InputInterface $input The input stream used to get the argument and verbose option. + * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. + * @return int 0 + */ + protected function run_all(InputInterface $input, OutputInterface $output) + { + $run_tasks = $this->cron_manager->find_all_ready_tasks(); + + if ($run_tasks) + { + foreach ($run_tasks as $task) + { + if ($input->getOption('verbose')) + { + $output->writeln('<info>' . $this->user->lang('RUNNING_TASK', $task->get_name()) . '</info>'); + } + + $task->run(); + } + } + else + { + if ($input->getOption('verbose')) + { + $output->writeln('<info>' . $this->user->lang('CRON_NO_TASK') . '</info>'); + } + } + + return 0; + } + + /* + * Executes a given cron task, if it is ready. + * + * If there is a task whose name matches $task_name, it is run and 0 is returned. + * and if verbose mode is set, print an info message with the name of the task. + * If there is no task matching $task_name, the function prints an error message + * and returns with status 2. + * + * @see execute + * @param string $task_name The name of the task that should be run. + * @param InputInterface $input The input stream used to get the argument and verbose option. + * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. + * @return int 0 if all is well, 2 if no task matches $task_name. + */ + protected function run_one(InputInterface $input, OutputInterface $output, $task_name) + { + $task = $this->cron_manager->find_task($task_name); + if ($task) + { + if ($input->getOption('verbose')) + { + $output->writeln('<info>' . $this->user->lang('RUNNING_TASK', $task_name) . '</info>'); + } + + $task->run(); + return 0; + } + else + { + $output->writeln('<error>' . $this->user->lang('CRON_NO_SUCH_TASK', $task_name) . '</error>'); + return 2; + } + } +} diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index 0f74664095..2abeaf5268 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -43,7 +43,7 @@ class migrate extends \phpbb\console\command\command $this->cache = $cache; $this->log = $log; $this->user = $user; - $this->user->add_lang(array('common', 'acp/common', 'install', 'migrator')); + $this->user->add_lang(array('common', 'install', 'migrator')); parent::__construct(); } diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php index 1eb8edf033..f04f063228 100644 --- a/phpBB/phpbb/cron/manager.php +++ b/phpBB/phpbb/cron/manager.php @@ -122,6 +122,16 @@ class manager } /** + * Find all tasks and return them. + * + * @return array List of all tasks. + */ + public function get_tasks() + { + return $this->tasks; + } + + /** * Wraps a task inside an instance of \phpbb\cron\task\wrapper. * * @param \phpbb\cron\task\task $task The task. diff --git a/phpBB/phpbb/db/migration/data/v310/beta4.php b/phpBB/phpbb/db/migration/data/v310/beta4.php new file mode 100644 index 0000000000..3e91d95178 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/beta4.php @@ -0,0 +1,33 @@ +<?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 beta4 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\beta3', + '\phpbb\db\migration\data\v310\extensions_version_check_force_unstable', + '\phpbb\db\migration\data\v310\reset_missing_captcha_plugin', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-b4')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php b/phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php new file mode 100644 index 0000000000..bd682e2f7c --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/contact_admin_acp_module.php @@ -0,0 +1,27 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class contact_admin_acp_module extends \phpbb\db\migration\migration +{ + public function update_data() + { + return array( + array('module.add', array( + 'acp', + 'ACP_BOARD_CONFIGURATION', + array( + 'module_basename' => 'acp_contact', + 'modes' => array('contact'), + ), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php new file mode 100644 index 0000000000..e255efb99d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php @@ -0,0 +1,37 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class contact_admin_form extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['contact_admin_form_enable']); + } + + public function update_data() + { + return array( + array('config.add', array('contact_admin_form_enable', 1)), + array('custom', array(array($this, 'contact_admin_info'))), + ); + } + + public function contact_admin_info() + { + $text_config = new \phpbb\config\db_text($this->db, $this->table_prefix . 'config_text'); + $text_config->set_array(array( + 'contact_admin_info' => '', + 'contact_admin_info_uid' => '', + 'contact_admin_info_bitfield' => '', + 'contact_admin_info_flags' => OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS, + )); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php b/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php index 5941c3aa54..1d6276f484 100644 --- a/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php +++ b/phpBB/phpbb/db/migration/data/v310/extensions_version_check_force_unstable.php @@ -1,9 +1,13 @@ <?php /** * -* @package migration -* @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* 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. * */ diff --git a/phpBB/phpbb/extension/finder.php b/phpBB/phpbb/extension/finder.php index 71a5542b67..6f2408094e 100644 --- a/phpBB/phpbb/extension/finder.php +++ b/phpBB/phpbb/extension/finder.php @@ -465,6 +465,10 @@ class finder } else if ($directory && $directory[0] === '/') { + if (!$is_dir) + { + $path .= substr($directory, 1); + } $directory_pattern = '^' . preg_quote(str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR, '#'); } else @@ -477,45 +481,56 @@ class finder } $directory_pattern = '#' . $directory_pattern . '#'; - $iterator = new \RecursiveIteratorIterator( - new \phpbb\recursive_dot_prefix_filter_iterator( - new \RecursiveDirectoryIterator( - $path, - \FilesystemIterator::SKIP_DOTS - ) - ), - \RecursiveIteratorIterator::SELF_FIRST - ); - - foreach ($iterator as $file_info) + if (is_dir($path)) { - $filename = $file_info->getFilename(); - - if ($file_info->isDir() == $is_dir) + $iterator = new \RecursiveIteratorIterator( + new \phpbb\recursive_dot_prefix_filter_iterator( + new \RecursiveDirectoryIterator( + $path, + \FilesystemIterator::SKIP_DOTS + ) + ), + \RecursiveIteratorIterator::SELF_FIRST + ); + + foreach ($iterator as $file_info) { - if ($is_dir) + $filename = $file_info->getFilename(); + + if ($file_info->isDir() == $is_dir) { - $relative_path = $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR . basename($filename) . DIRECTORY_SEPARATOR; - if ($relative_path[0] !== DIRECTORY_SEPARATOR) + if ($is_dir) { - $relative_path = DIRECTORY_SEPARATOR . $relative_path; + $relative_path = $iterator->getInnerIterator()->getSubPath() . DIRECTORY_SEPARATOR . basename($filename) . DIRECTORY_SEPARATOR; + if ($relative_path[0] !== DIRECTORY_SEPARATOR) + { + $relative_path = DIRECTORY_SEPARATOR . $relative_path; + } + } + else + { + $relative_path = $iterator->getInnerIterator()->getSubPathname(); + if ($directory && $directory[0] === '/') + { + $relative_path = str_replace('/', DIRECTORY_SEPARATOR, $directory) . DIRECTORY_SEPARATOR . $relative_path; + } + else + { + $relative_path = DIRECTORY_SEPARATOR . $relative_path; + } } - } - else - { - $relative_path = DIRECTORY_SEPARATOR . $iterator->getInnerIterator()->getSubPathname(); - } - if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) && - (!$prefix || substr($filename, 0, strlen($prefix)) === $prefix) && - (!$directory || preg_match($directory_pattern, $relative_path))) - { - $files[] = array( - 'named_path' => str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . substr($relative_path, 1)), - 'ext_name' => $ext_name, - 'path' => str_replace(array(DIRECTORY_SEPARATOR, $this->phpbb_root_path), array('/', ''), $file_info->getPath()) . '/', - 'filename' => $filename, - ); + if ((!$suffix || substr($relative_path, -strlen($suffix)) === $suffix) && + (!$prefix || substr($filename, 0, strlen($prefix)) === $prefix) && + (!$directory || preg_match($directory_pattern, $relative_path))) + { + $files[] = array( + 'named_path' => str_replace(DIRECTORY_SEPARATOR, '/', $location . $name . substr($relative_path, 1)), + 'ext_name' => $ext_name, + 'path' => str_replace(array(DIRECTORY_SEPARATOR, $this->phpbb_root_path), array('/', ''), $file_info->getPath()) . '/', + 'filename' => $filename, + ); + } } } } diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 0bfec23573..cd7289e085 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -26,6 +26,7 @@ class manager protected $db; protected $config; protected $cache; + protected $user; protected $php_ext; protected $extensions; protected $extension_table; @@ -37,25 +38,27 @@ class manager * * @param ContainerInterface $container A container * @param \phpbb\db\driver\driver_interface $db A database connection - * @param \phpbb\config\config $config \phpbb\config\config + * @param \phpbb\config\config $config Config object * @param \phpbb\filesystem $filesystem + * @param \phpbb\user $user User object * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. - * @param string $php_ext php file extension + * @param string $php_ext php file extension, defaults to php * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, \phpbb\user $user, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') { + $this->cache = $cache; + $this->cache_name = $cache_name; + $this->config = $config; $this->container = $container; - $this->phpbb_root_path = $phpbb_root_path; $this->db = $db; - $this->config = $config; - $this->cache = $cache; + $this->extension_table = $extension_table; $this->filesystem = $filesystem; + $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->extension_table = $extension_table; - $this->cache_name = $cache_name; + $this->user = $user; $this->extensions = ($this->cache) ? $this->cache->get($this->cache_name) : false; @@ -150,7 +153,7 @@ class manager */ public function create_extension_metadata_manager($name, \phpbb\template\template $template) { - return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->phpbb_root_path); + return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->user, $this->phpbb_root_path); } /** diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 047f0ca54c..5c4e8fbf00 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -37,6 +37,12 @@ class metadata_manager protected $template; /** + * phpBB User instance + * @var \phpbb\user + */ + protected $user; + + /** * phpBB root path * @var string */ @@ -65,15 +71,17 @@ class metadata_manager * * @param string $ext_name Name (including vendor) of the extension * @param \phpbb\config\config $config phpBB Config instance - * @param \phpbb\extension\manager $extension_manager An instance of the phpBBb extension manager - * @param \phpbb\template\template $template phpBB Template instance + * @param \phpbb\extension\manager $extension_manager An instance of the phpBB extension manager + * @param \phpbb\template\template $template phpBB Template instance + * @param \phpbb\user $user User instance * @param string $phpbb_root_path Path to the phpbb includes directory. */ - public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, $phpbb_root_path) + public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, \phpbb\user $user, $phpbb_root_path) { $this->config = $config; $this->extension_manager = $extension_manager; $this->template = $template; + $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; $this->ext_name = $ext_name; @@ -141,7 +149,7 @@ class metadata_manager if (!file_exists($this->metadata_file)) { - throw new \phpbb\extension\exception('The required file does not exist: ' . $this->metadata_file); + throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file)); } } @@ -154,18 +162,18 @@ class metadata_manager { if (!file_exists($this->metadata_file)) { - throw new \phpbb\extension\exception('The required file does not exist: ' . $this->metadata_file); + throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file)); } else { if (!($file_contents = file_get_contents($this->metadata_file))) { - throw new \phpbb\extension\exception('file_get_contents failed on ' . $this->metadata_file); + throw new \phpbb\extension\exception($this->user->lang('FILE_CONTENT_ERR', $this->metadata_file)); } if (($metadata = json_decode($file_contents, true)) === null) { - throw new \phpbb\extension\exception('json_decode failed on ' . $this->metadata_file); + throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file)); } $this->metadata = $metadata; @@ -224,12 +232,12 @@ class metadata_manager { if (!isset($this->metadata[$name])) { - throw new \phpbb\extension\exception("Required meta field '$name' has not been set."); + throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', $name)); } if (!preg_match($fields[$name], $this->metadata[$name])) { - throw new \phpbb\extension\exception("Meta field '$name' is invalid."); + throw new \phpbb\extension\exception($this->user->lang('META_FIELD_INVALID', $name)); } } break; @@ -247,14 +255,14 @@ class metadata_manager { if (empty($this->metadata['authors'])) { - throw new \phpbb\extension\exception("Required meta field 'authors' has not been set."); + throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'authors')); } foreach ($this->metadata['authors'] as $author) { if (!isset($author['name'])) { - throw new \phpbb\extension\exception("Required meta field 'author name' has not been set."); + throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'author name')); } } diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index d83fa90a8e..10efe5fd1c 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -332,6 +332,99 @@ class log implements \phpbb\log\log_interface } /** + * {@inheritDoc} + */ + public function delete($mode, $conditions = array()) + { + switch ($mode) + { + case 'admin': + $log_type = LOG_ADMIN; + break; + + case 'mod': + $log_type = LOG_MOD; + break; + + case 'user': + $log_type = LOG_USERS; + break; + + case 'users': + $log_type = LOG_USERS; + break; + + case 'critical': + $log_type = LOG_CRITICAL; + break; + + default: + $log_type = false; + } + + /** + * Allows to modify log data before we delete it from the database + * + * NOTE: if sql_ary does not contain a log_type value, the entry will + * not be deleted in the database. So ensure to set it, if needed. + * + * @event core.delete_log + * @var string mode Mode of the entry we log + * @var string log_type Type ID of the log (should be different than false) + * @var array conditions An array of conditions, 3 different forms are accepted + * 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer) + * 2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array) + * 3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>' + * A special field, keywords, can also be defined. In this case only the log entries that have the keywords in log_operation or log_data will be deleted. + * @since 3.1.0-b4 + */ + $vars = array( + 'mode', + 'log_type', + 'conditions', + ); + extract($this->dispatcher->trigger_event('core.delete_log', compact($vars))); + + if ($log_type === false) + { + return; + } + + $sql_where = 'WHERE log_type = ' . $log_type; + + if (isset($conditions['keywords'])) + { + $sql_where .= $this->generate_sql_keyword($conditions['keywords'], ''); + + unset($conditions['keywords']); + } + + foreach ($conditions as $field => $field_value) + { + $sql_where .= ' AND '; + + if (is_array($field_value) && sizeof($field_value) == 2 && !is_array($field_value[1])) + { + $sql_where .= $field . ' ' . $field_value[0] . ' ' . $field_value[1]; + } + else if (is_array($field_value) && isset($field_value['IN']) && is_array($field_value['IN'])) + { + $sql_where .= $this->db->sql_in_set($field, $field_value['IN']); + } + else + { + $sql_where .= $field . ' = ' . $field_value; + } + } + + $sql = 'DELETE FROM ' . LOG_TABLE . " + $sql_where"; + $this->db->sql_query($sql); + + $this->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_CLEAR_' . strtoupper($mode)); + } + + /** * Grab the logs from the database * * {@inheritDoc} @@ -638,11 +731,13 @@ class log implements \phpbb\log\log_interface /** * Generates a sql condition for the specified keywords * - * @param string $keywords The keywords the user specified to search for + * @param string $keywords The keywords the user specified to search for + * @param string $table_alias The alias of the logs' table ('l.' by default) + * @param string $statement_operator The operator used to prefix the statement ('AND' by default) * * @return string Returns the SQL condition searching for the keywords */ - protected function generate_sql_keyword($keywords) + protected function generate_sql_keyword($keywords, $table_alias = 'l.', $statement_operator = 'AND') { // Use no preg_quote for $keywords because this would lead to sole // backslashes being added. We also use an OR connection here for @@ -687,12 +782,12 @@ class log implements \phpbb\log\log_interface } } - $sql_keywords = 'AND ('; + $sql_keywords = ' ' . $statement_operator . ' ('; if (!empty($operations)) { - $sql_keywords .= $this->db->sql_in_set('l.log_operation', $operations) . ' OR '; + $sql_keywords .= $this->db->sql_in_set($table_alias . 'log_operation', $operations) . ' OR '; } - $sql_lower = $this->db->sql_lower_text('l.log_data'); + $sql_lower = $this->db->sql_lower_text($table_alias . 'log_data'); $sql_keywords .= " $sql_lower " . implode(" OR $sql_lower ", $keywords) . ')'; } diff --git a/phpBB/phpbb/log/log_interface.php b/phpBB/phpbb/log/log_interface.php index 2a44ebecb6..5932f722aa 100644 --- a/phpBB/phpbb/log/log_interface.php +++ b/phpBB/phpbb/log/log_interface.php @@ -69,6 +69,18 @@ interface log_interface public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array()); /** + * Delete entries in the logs + * + * @param string $mode The mode defines which log_type is used and from which log the entries are deleted + * @param array $conditions An array of conditions, 3 different forms are accepted + * 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer) + * 2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array) + * 3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>' + * A special field, keywords, can also be defined. In this case only the log entries that have the keywords in log_operation or log_data will be deleted. + */ + public function delete($mode, $conditions = array()); + + /** * Grab the logs from the database * * @param string $mode The mode defines which log_type is used and ifrom which log the entry is retrieved diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/null.php index 7b11cc9e21..baa78895ea 100644 --- a/phpBB/phpbb/log/null.php +++ b/phpBB/phpbb/log/null.php @@ -51,6 +51,13 @@ class null implements log_interface /** * {@inheritdoc} */ + public function delete($mode, $conditions = array()) + { + } + + /** + * {@inheritdoc} + */ public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '') { return array(); diff --git a/phpBB/phpbb/message/admin_form.php b/phpBB/phpbb/message/admin_form.php new file mode 100644 index 0000000000..b71b3fc535 --- /dev/null +++ b/phpBB/phpbb/message/admin_form.php @@ -0,0 +1,189 @@ +<?php +/** +* +* @package message +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\message; + +/** +* Class admin_form +* Displays a message to the user and allows him to send an email +* +* @package phpbb\message +*/ +class admin_form extends form +{ + /** @var \phpbb\config\db_text */ + protected $config_text; + + /** @var string */ + protected $subject; + /** @var string */ + protected $sender_name; + /** @var string */ + protected $sender_address; + + /** + * Construct + * + * @param \phpbb\auth\auth $auth + * @param \phpbb\config\config $config + * @param \phpbb\config\db_text $config_text + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\user $user + * @param string $phpbb_root_path + * @param string $phpEx + */ + public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $phpEx) + { + parent::__construct($auth, $config, $db, $user, $phpbb_root_path, $phpEx); + $this->config_text = $config_text; + } + + /** + * {inheritDoc} + */ + public function check_allow() + { + $error = parent::check_allow(); + if ($error) + { + return $error; + } + + if (!$this->config['contact_admin_form_enable']) + { + return 'NO_CONTACT_PAGE'; + } + + return false; + } + + /** + * {inheritDoc} + */ + public function bind(\phpbb\request\request_interface $request) + { + parent::bind($request); + + $this->subject = $request->variable('subject', '', true); + $this->sender_address = $request->variable('email', ''); + $this->sender_name = $request->variable('name', '', true); + } + + /** + * {inheritDoc} + */ + public function submit(\messenger $messenger) + { + if (!$this->subject) + { + $this->errors[] = $this->user->lang['EMPTY_SUBJECT_EMAIL']; + } + if (!$this->body) + { + $this->errors[] = $this->user->lang['EMPTY_MESSAGE_EMAIL']; + } + + if ($this->user->data['is_registered']) + { + $this->message->set_sender_from_user($this->user); + $this->sender_name = $this->user->data['username']; + $this->sender_address = $this->user->data['user_email']; + } + else + { + if (!$this->sender_name) + { + $this->errors[] = $this->user->lang['EMPTY_SENDER_NAME']; + } + + if (!function_exists('validate_data')) + { + require($this->phpbb_root_path . 'includes/functions_user.' . $this->phpEx); + } + + $validate_array = validate_data( + array( + 'email' => $this->sender_address, + ), + array( + 'email' => array( + array('string', false, 6, 60), + array('email'), + ), + ) + ); + + foreach ($validate_array as $error) + { + $this->errors[] = $this->user->lang[$error]; + } + + $this->message->set_sender($this->user->ip, $this->sender_name, $this->sender_address, $this->user->lang_name); + $this->message->set_sender_notify_type(NOTIFY_EMAIL); + } + + $this->message->set_template('contact_admin'); + $this->message->set_subject($this->subject); + $this->message->set_body($this->body); + $this->message->add_recipient( + $this->user->lang['ADMINISTRATOR'], + $this->config['board_contact'], + $this->config['default_lang'], + NOTIFY_EMAIL + ); + + $this->message->set_template_vars(array( + 'FROM_EMAIL_ADDRESS' => $this->sender_address, + 'FROM_IP_ADDRESS' => $this->user->ip, + 'S_IS_REGISTERED' => $this->user->data['is_registered'], + + 'U_FROM_PROFILE' => generate_board_url() . '/memberlist.' . $this->phpEx . '?mode=viewprofile&u=' . $this->user->data['user_id'], + )); + + parent::submit($messenger); + } + + /** + * {inheritDoc} + */ + public function render(\phpbb\template\template $template) + { + $l_admin_info = $this->config_text->get('contact_admin_info'); + if ($l_admin_info) + { + $contact_admin_data = $this->config_text->get_array(array( + 'contact_admin_info', + 'contact_admin_info_uid', + 'contact_admin_info_bitfield', + 'contact_admin_info_flags', + )); + + $l_admin_info = generate_text_for_display( + $contact_admin_data['contact_admin_info'], + $contact_admin_data['contact_admin_info_uid'], + $contact_admin_data['contact_admin_info_bitfield'], + $contact_admin_data['contact_admin_info_flags'] + ); + } + + $template->assign_vars(array( + 'S_CONTACT_ADMIN' => true, + 'S_CONTACT_FORM' => $this->config['contact_admin_form_enable'], + 'S_IS_REGISTERED' => $this->user->data['is_registered'], + + 'CONTACT_INFO' => $l_admin_info, + 'MESSAGE' => $this->body, + 'SUBJECT' => $this->subject, + 'NAME' => $this->sender_name, + 'EMAIL' => $this->sender_address, + )); + + parent::render($template); + } +} diff --git a/phpBB/phpbb/message/form.php b/phpBB/phpbb/message/form.php new file mode 100644 index 0000000000..d7a42c4080 --- /dev/null +++ b/phpBB/phpbb/message/form.php @@ -0,0 +1,173 @@ +<?php +/** +* +* @package message +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\message; + +/** +* Abstract class form +* +* @package phpbb\message +*/ +abstract class form +{ + /** @var \phpbb\auth\auth */ + protected $auth; + /** @var \phpbb\config\config */ + protected $config; + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + /** @var \phpbb\message\message */ + protected $message; + /** @var \phpbb\user */ + protected $user; + + /** @var string */ + protected $phpbb_root_path; + /** @var string */ + protected $phpEx; + + /** @var array */ + protected $errors = array(); + /** @var bool */ + protected $cc_sender; + /** @var string */ + protected $body; + + /** + * Construct + * + * @param \phpbb\auth\auth $auth + * @param \phpbb\config\config $config + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\user $user + * @param string $phpbb_root_path + * @param string $phpEx + */ + public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $phpEx) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->phpEx = $phpEx; + $this->user = $user; + $this->auth = $auth; + $this->config = $config; + $this->db = $db; + + $this->message = new message($config['server_name']); + $this->message->set_sender_from_user($this->user); + } + + /** + * Returns the title for the email form page + * + * @return string + */ + public function get_page_title() + { + return $this->user->lang['SEND_EMAIL']; + } + + /** + * Returns the file name of the form template + * + * @return string + */ + public function get_template_file() + { + return 'memberlist_email.html'; + } + + /** + * Checks whether the user is allowed to use the form + * + * @return false|string Error string if not allowed, false otherwise + */ + public function check_allow() + { + if (!$this->config['email_enable']) + { + return 'EMAIL_DISABLED'; + } + + if (time() - $this->user->data['user_emailtime'] < $this->config['flood_interval']) + { + return 'FLOOD_EMAIL_LIMIT'; + } + + return false; + } + + /** + * Get the return link after the message has been sent + * + * @return string + */ + public function get_return_message() + { + return sprintf($this->user->lang['RETURN_INDEX'], '<a href="' . append_sid($this->phpbb_root_path . 'index.' . $this->phpEx) . '">', '</a>'); + } + + /** + * Bind the values of the request to the form + * + * @param \phpbb\request\request_interface $request + * @return null + */ + public function bind(\phpbb\request\request_interface $request) + { + $this->cc_sender = $request->is_set_post('cc_sender'); + $this->body = $request->variable('message', '', true); + } + + /** + * Submit form, generate the email and send it + * + * @param \messenger $messenger + * @return null + */ + public function submit(\messenger $messenger) + { + if (!check_form_key('memberlist_email')) + { + $this->errors[] = 'FORM_INVALID'; + } + + if (!sizeof($this->errors)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_emailtime = ' . time() . ' + WHERE user_id = ' . $this->user->data['user_id']; + $this->db->sql_query($sql); + + if ($this->cc_sender) + { + $this->message->cc_sender(); + } + + $this->message->send($messenger, phpbb_get_board_contact($this->config, $this->phpEx)); + + meta_refresh(3, append_sid($this->phpbb_root_path . 'index.' . $this->phpEx)); + trigger_error($this->user->lang['EMAIL_SENT'] . '<br /><br />' . $this->get_return_message()); + } + } + + /** + * Render the template of the form + * + * @param \phpbb\template\template $template + * @return null + */ + public function render(\phpbb\template\template $template) + { + add_form_key('memberlist_email'); + + $template->assign_vars(array( + 'ERROR_MESSAGE' => (sizeof($this->errors)) ? implode('<br />', $this->errors) : '', + )); + } +} diff --git a/phpBB/phpbb/message/message.php b/phpBB/phpbb/message/message.php new file mode 100644 index 0000000000..182995ba21 --- /dev/null +++ b/phpBB/phpbb/message/message.php @@ -0,0 +1,280 @@ +<?php +/** +* +* @package message +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\message; + +/** +* Class message +* Holds all information for an email and sends it in the end +* +* @package phpbb\message +*/ +class message +{ + /** @var string */ + protected $server_name; + + /** @var string */ + protected $subject = ''; + /** @var string */ + protected $body = ''; + /** @var string */ + protected $template = ''; + /** @var array */ + protected $template_vars = array(); + + /** @var string */ + protected $sender_ip = ''; + /** @var string */ + protected $sender_name = ''; + /** @var string */ + protected $sender_address = ''; + /** @var string */ + protected $sender_lang = ''; + /** @var string */ + protected $sender_id = ''; + /** @var string */ + protected $sender_username = ''; + /** @var string */ + protected $sender_jabber = ''; + /** @var int */ + protected $sender_notify_type = NOTIFY_EMAIL; + + /** @var array */ + protected $recipients; + + /** + * Construct + * + * @param string $server_name Used for AntiAbuse header + */ + public function __construct($server_name) + { + $this->server_name = $server_name; + } + + /** + * Set the subject of the email + * + * @param string $subject + * @return null + */ + public function set_subject($subject) + { + $this->subject = $subject; + } + + /** + * Set the body of the email text + * + * @param string $body + * @return null + */ + public function set_body($body) + { + $this->body = $body; + } + + /** + * Set the name of the email template to use + * + * @param string $template + * @return null + */ + public function set_template($template) + { + $this->template = $template; + } + + /** + * Set the array with the "template" data for the email + * + * @param array $template_vars + * @return null + */ + public function set_template_vars($template_vars) + { + $this->template_vars = $template_vars; + } + + /** + * Add a recipient from \phpbb\user + * + * @param \phpbb\user $user + * @return null + */ + public function add_recipient_from_user_row(array $user) + { + $this->add_recipient( + $user['username'], + $user['user_email'], + $user['user_lang'], + $user['user_notify_type'], + $user['username'], + $user['user_jabber'] + ); + } + + /** + * Add a recipient + * + * @param string $recipient_name Displayed sender name + * @param string $recipient_address Email address + * @param string $recipient_lang + * @param int $recipient_notify_type Used notification methods (Jabber, Email, ...) + * @param string $recipient_username User Name (used for AntiAbuse header) + * @param string $recipient_jabber + * @return null + */ + public function add_recipient($recipient_name, $recipient_address, $recipient_lang, $recipient_notify_type = NOTIFY_EMAIL, $recipient_username = '', $recipient_jabber = '') + { + $this->recipients[] = array( + 'name' => $recipient_name, + 'address' => $recipient_address, + 'lang' => $recipient_lang, + 'username' => $recipient_username, + 'jabber' => $recipient_jabber, + 'notify_type' => $recipient_notify_type, + 'to_name' => $recipient_name, + ); + } + + /** + * Set the senders data from \phpbb\user object + * + * @param \phpbb\user $user + * @return null + */ + public function set_sender_from_user($user) + { + $this->set_sender( + $user->ip, + $user->data['username'], + $user->data['user_email'], + $user->lang_name, + $user->data['user_id'], + $user->data['username'], + $user->data['user_jabber'] + ); + + $this->set_sender_notify_type($user->data['user_notify_type']); + } + + /** + * Set the senders data + * + * @param string $sender_ip + * @param string $sender_name Displayed sender name + * @param string $sender_address Email address + * @param string $sender_lang + * @param int $sender_id User ID + * @param string $sender_username User Name (used for AntiAbuse header) + * @param string $sender_jabber + * @return null + */ + public function set_sender($sender_ip, $sender_name, $sender_address, $sender_lang = '', $sender_id = 0, $sender_username = '', $sender_jabber = '') + { + $this->sender_ip = $sender_ip; + $this->sender_name = $sender_name; + $this->sender_address = $sender_address; + $this->sender_lang = $sender_lang; + $this->sender_id = $sender_id; + $this->sender_username = $sender_username; + $this->sender_jabber = $sender_jabber; + } + + /** + * Which notification type should be used? Jabber, Email, ...? + * + * @param int $sender_notify_type + * @return null + */ + public function set_sender_notify_type($sender_notify_type) + { + $this->sender_notify_type = $sender_notify_type; + } + + /** + * Ok, now the same email if CC specified, but without exposing the user's email address + * + * @return null + */ + public function cc_sender() + { + if (!sizeof($this->recipients)) + { + trigger_error('No email recipients specified'); + } + if (!$this->sender_address) + { + trigger_error('No email sender specified'); + } + + $this->recipients[] = array( + 'lang' => $this->sender_lang, + 'address' => $this->sender_address, + 'name' => $this->sender_name, + 'username' => $this->sender_username, + 'jabber' => $this->sender_jabber, + 'notify_type' => $this->sender_notify_type, + 'to_name' => $this->recipients[0]['to_name'], + ); + } + + /** + * Send the email + * + * @param \messenger $messenger + * @param string $phpEx + * @return null + */ + public function send(\messenger $messenger, $contact) + { + if (!sizeof($this->recipients)) + { + return; + } + + foreach ($this->recipients as $recipient) + { + $messenger->template($this->template, $recipient['lang']); + $messenger->replyto($this->sender_address); + $messenger->to($recipient['address'], $recipient['name']); + $messenger->im($recipient['jabber'], $recipient['username']); + + $messenger->headers('X-AntiAbuse: Board servername - ' . $this->server_name); + $messenger->headers('X-AntiAbuse: User IP - ' . $this->sender_ip); + + if ($this->sender_id) + { + $messenger->headers('X-AntiAbuse: User_id - ' . $this->sender_id); + } + if ($this->sender_username) + { + $messenger->headers('X-AntiAbuse: Username - ' . $this->sender_username); + } + + $messenger->subject(htmlspecialchars_decode($this->subject)); + + $messenger->assign_vars(array( + 'BOARD_CONTACT' => $contact, + 'TO_USERNAME' => htmlspecialchars_decode($recipient['to_name']), + 'FROM_USERNAME' => htmlspecialchars_decode($this->sender_name), + 'MESSAGE' => htmlspecialchars_decode($this->body)) + ); + + if (sizeof($this->template_vars)) + { + $messenger->assign_vars($this->template_vars); + } + + $messenger->send($recipient['notify_type']); + } + } +} diff --git a/phpBB/phpbb/message/topic_form.php b/phpBB/phpbb/message/topic_form.php new file mode 100644 index 0000000000..3a35c35d21 --- /dev/null +++ b/phpBB/phpbb/message/topic_form.php @@ -0,0 +1,156 @@ +<?php +/** +* +* @package message +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\message; + +/** +* Class topic_form +* Form used to send topics as notification emails +* +* @package phpbb\message +*/ +class topic_form extends form +{ + /** @var int */ + protected $topic_id; + /** @var array */ + protected $topic_row; + /** @var string */ + protected $recipient_address; + /** @var string */ + protected $recipient_name; + /** @var string */ + protected $recipient_lang; + + /** + * Get the data of the topic + * + * @param int $topic_id + * @return false|array false if the topic does not exist, array otherwise + */ + protected function get_topic_row($topic_id) + { + $sql = 'SELECT forum_id, topic_title + FROM ' . TOPICS_TABLE . ' + WHERE topic_id = ' . (int) $topic_id; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return $row; + } + + /** + * {inheritDoc} + */ + public function check_allow() + { + $error = parent::check_allow(); + if ($error) + { + return $error; + } + + if (!$this->auth->acl_get('u_sendemail')) + { + return 'NO_EMAIL'; + } + + if (!$this->topic_row) + { + return 'NO_TOPIC'; + } + + if (!$this->auth->acl_get('f_read', $this->topic_row['forum_id'])) + { + return 'SORRY_AUTH_READ'; + } + + if (!$this->auth->acl_get('f_email', $this->topic_row['forum_id'])) + { + return 'NO_EMAIL'; + } + + return false; + } + + /** + * {inheritDoc} + */ + public function bind(\phpbb\request\request_interface $request) + { + parent::bind($request); + + $this->topic_id = $request->variable('t', 0); + $this->recipient_address = $request->variable('email', ''); + $this->recipient_name = $request->variable('name', '', true); + $this->recipient_lang = $request->variable('lang', $this->config['default_lang']); + + $this->topic_row = $this->get_topic_row($this->topic_id); + } + + /** + * {inheritDoc} + */ + public function submit(\messenger $messenger) + { + if (!$this->recipient_address || !preg_match('/^' . get_preg_expression('email') . '$/i', $this->recipient_address)) + { + $this->errors[] = $this->user->lang['EMPTY_ADDRESS_EMAIL']; + } + + if (!$this->recipient_name) + { + $this->errors[] = $this->user->lang['EMPTY_NAME_EMAIL']; + } + + $this->message->set_template('email_notify'); + $this->message->set_template_vars(array( + 'TOPIC_NAME' => htmlspecialchars_decode($this->topic_row['topic_title']), + 'U_TOPIC' => generate_board_url() . '/viewtopic.' . $this->phpEx . '?f=' . $this->topic_row['forum_id'] . '&t=' . $this->topic_id, + )); + + $this->message->add_recipient( + $this->recipient_name, + $this->recipient_address, + $this->recipient_lang, + NOTIFY_EMAIL + ); + $this->message->set_sender_notify_type(NOTIFY_EMAIL); + + parent::submit($messenger); + } + + /** + * {inheritDoc} + */ + public function get_return_message() + { + return sprintf($this->user->lang['RETURN_TOPIC'], '<a href="' . append_sid($this->phpbb_root_path . 'viewtopic.' . $this->phpEx, 'f=' . $this->topic_row['forum_id'] . '&t=' . $this->topic_id) . '">', '</a>'); + } + + /** + * {inheritDoc} + */ + public function render(\phpbb\template\template $template) + { + parent::render($template); + + $this->user->add_lang('viewtopic'); + $template->assign_vars(array( + 'EMAIL' => $this->recipient_address, + 'NAME' => $this->recipient_name, + 'S_LANG_OPTIONS' => language_select($this->recipient_lang), + 'MESSAGE' => $this->body, + + 'L_EMAIL_BODY_EXPLAIN' => $this->user->lang['EMAIL_TOPIC_EXPLAIN'], + 'S_POST_ACTION' => append_sid($this->phpbb_root_path . 'memberlist.' . $this->phpEx, 'mode=email&t=' . $this->topic_id)) + ); + } +} diff --git a/phpBB/phpbb/message/user_form.php b/phpBB/phpbb/message/user_form.php new file mode 100644 index 0000000000..7aa4b94def --- /dev/null +++ b/phpBB/phpbb/message/user_form.php @@ -0,0 +1,134 @@ +<?php +/** +* +* @package message +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\message; + +/** +* Class user_form +* Allows users to send emails to other users +* +* @package phpbb\message +*/ +class user_form extends form +{ + /** @var int */ + protected $recipient_id; + /** @var array */ + protected $recipient_row; + /** @var string */ + protected $subject; + + /** + * Get the data of the recipient + * + * @param int $user_id + * @return false|array false if the user does not exist, array otherwise + */ + protected function get_user_row($user_id) + { + $sql = 'SELECT user_id, username, user_colour, user_email, user_allow_viewemail, user_lang, user_jabber, user_notify_type + FROM ' . USERS_TABLE . ' + WHERE user_id = ' . (int) $user_id . ' + AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return $row; + } + + /** + * {inheritDoc} + */ + public function check_allow() + { + $error = parent::check_allow(); + if ($error) + { + return $error; + } + + if (!$this->auth->acl_get('u_sendemail')) + { + return 'NO_EMAIL'; + } + + if ($this->recipient_id == ANONYMOUS || !$this->config['board_email_form']) + { + return 'NO_EMAIL'; + } + + if (!$this->recipient_row) + { + return 'NO_USER'; + } + + // Can we send email to this user? + if (!$this->recipient_row['user_allow_viewemail'] && !$this->auth->acl_get('a_user')) + { + return 'NO_EMAIL'; + } + + return false; + } + + /** + * {inheritDoc} + */ + public function bind(\phpbb\request\request_interface $request) + { + parent::bind($request); + + $this->recipient_id = $request->variable('u', 0); + $this->subject = $request->variable('subject', '', true); + + $this->recipient_row = $this->get_user_row($this->recipient_id); + } + + /** + * {inheritDoc} + */ + public function submit(\messenger $messenger) + { + if (!$this->subject) + { + $this->errors[] = $this->user->lang['EMPTY_SUBJECT_EMAIL']; + } + + if (!$this->body) + { + $this->errors[] = $this->user->lang['EMPTY_MESSAGE_EMAIL']; + } + + $this->message->set_template('profile_send_email'); + $this->message->set_subject($this->subject); + $this->message->set_body($this->body); + $this->message->add_recipient_from_user_row($this->recipient_row); + + parent::submit($messenger); + } + + /** + * {inheritDoc} + */ + public function render(\phpbb\template\template $template) + { + parent::render($template); + + $template->assign_vars(array( + 'S_SEND_USER' => true, + 'S_POST_ACTION' => append_sid($this->phpbb_root_path . 'memberlist.' . $this->phpEx, 'mode=email&u=' . $this->recipient_id), + + 'L_SEND_EMAIL_USER' => $this->user->lang('SEND_EMAIL_USER', $this->recipient_row['username']), + 'USERNAME_FULL' => get_username_string('full', $this->recipient_row['user_id'], $this->recipient_row['username'], $this->recipient_row['user_colour']), + 'SUBJECT' => $this->subject, + 'MESSAGE' => $this->body, + )); + } +} diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index d286dc9cfc..c2669ea6cc 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -1075,7 +1075,7 @@ class session { global $config, $db; - if (defined('IN_CHECK_BAN')) + if (defined('IN_CHECK_BAN') || defined('SKIP_CHECK_BAN')) { return; } @@ -1189,7 +1189,7 @@ class session if ($banned && !$return) { - global $template; + global $template, $phpbb_root_path, $phpEx; // If the session is empty we need to create a valid one... if (empty($this->session_id)) @@ -1210,8 +1210,6 @@ class session // We show a login box here to allow founders accessing the board if banned by IP if (defined('IN_LOGIN') && $this->data['user_id'] == ANONYMOUS) { - global $phpEx; - $this->setup('ucp'); $this->data['is_registered'] = $this->data['is_bot'] = false; @@ -1235,7 +1233,8 @@ class session $till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : ''; $message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM'; - $message = sprintf($this->lang[$message], $till_date, '<a href="mailto:' . $config['board_contact'] . '">', '</a>'); + $contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx); + $message = sprintf($this->lang[$message], $till_date, '<a href="' . $contact_link . '">', '</a>'); $message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : ''; $message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>'; diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index f4cc26cc9a..4e90044395 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -317,7 +317,7 @@ class user extends \phpbb\session } // Is board disabled and user not an admin or moderator? - if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) + if ($config['board_disable'] && !defined('IN_LOGIN') && !defined('SKIP_CHECK_DISABLED') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) { if ($this->data['is_bot']) { |