<?php
/**
*
* Advertisement management. An extension for the phpBB Forum Software package.
*
* @copyright (c) 2017 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/
namespace phpbb\ads\controller;
use phpbb\ads\ext;
/**
* Admin controller
*/
class admin_controller
{
/** @var array Form data */
protected $data = array();
/** @var \phpbb\template\template */
protected $template;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\request\request */
protected $request;
/** @var \phpbb\ads\ad\manager */
protected $manager;
/** @var \phpbb\config\db_text */
protected $config_text;
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\ads\controller\admin_input */
protected $input;
/** @var \phpbb\ads\controller\helper */
protected $helper;
/** @var \phpbb\ads\analyser\manager */
protected $analyser;
/** @var \phpbb\controller\helper */
protected $controller_helper;
/** @var string Custom form action */
protected $u_action;
/** @var \auth_admin Auth admin */
protected $auth_admin;
/**
* Constructor
*
* @param \phpbb\template\template $template Template object
* @param \phpbb\language\language $language Language object
* @param \phpbb\request\request $request Request object
* @param \phpbb\ads\ad\manager $manager Advertisement manager object
* @param \phpbb\config\db_text $config_text Config text object
* @param \phpbb\config\config $config Config object
* @param \phpbb\ads\controller\admin_input $input Admin input object
* @param \phpbb\ads\controller\helper $helper Helper object
* @param \phpbb\ads\analyser\manager $analyser Ad code analyser object
* @param \phpbb\controller\helper $controller_helper Controller helper object
* @param string $root_path phpBB root path
* @param string $php_ext PHP extension
*/
public function __construct(\phpbb\template\template $template, \phpbb\language\language $language, \phpbb\request\request $request, \phpbb\ads\ad\manager $manager, \phpbb\config\db_text $config_text, \phpbb\config\config $config, \phpbb\ads\controller\admin_input $input, \phpbb\ads\controller\helper $helper, \phpbb\ads\analyser\manager $analyser, \phpbb\controller\helper $controller_helper, $root_path, $php_ext)
{
$this->template = $template;
$this->language = $language;
$this->request = $request;
$this->manager = $manager;
$this->config_text = $config_text;
$this->config = $config;
$this->input = $input;
$this->helper = $helper;
$this->analyser = $analyser;
$this->controller_helper = $controller_helper;
$this->language->add_lang('posting'); // Used by banner_upload() file errors
$this->language->add_lang('acp', 'phpbb/ads');
$this->template->assign_var('S_PHPBB_ADS', true);
if (!class_exists('auth_admin'))
{
include($root_path . 'includes/acp/auth.' . $php_ext);
}
$this->auth_admin = new \auth_admin();
}
/**
* Set page url
*
* @param string $u_action Custom form action
* @return void
*/
public function set_page_url($u_action)
{
$this->u_action = $u_action;
}
/**
* Get ACP page title for Ads module
*
* @return string Language string for Ads ACP module
*/
public function get_page_title()
{
return $this->language->lang('ACP_PHPBB_ADS_TITLE');
}
/**
* Process user request for settings mode
*
* @return void
*/
public function mode_settings()
{
if ($this->request->is_set_post('submit'))
{
// Validate form key
if (check_form_key('phpbb_ads'))
{
$this->config->set('phpbb_ads_adblocker_message', $this->request->variable('adblocker_message', 0));
$this->config->set('phpbb_ads_enable_views', $this->request->variable('enable_views', 0));
$this->config->set('phpbb_ads_enable_clicks', $this->request->variable('enable_clicks', 0));
$this->success('ACP_AD_SETTINGS_SAVED');
}
$this->error('FORM_INVALID');
}
$this->template->assign_vars(array(
'U_ACTION' => $this->u_action,
'AD_BLOCK_MODES' => ext::AD_BLOCK_MODES,
'AD_BLOCK_CONFIG' => $this->config['phpbb_ads_adblocker_message'],
'ENABLE_VIEWS' => $this->config['phpbb_ads_enable_views'],
'ENABLE_CLICKS' => $this->config['phpbb_ads_enable_clicks'],
));
}
/**
* Process user request for manage mode
*
* @return void
*/
public function mode_manage()
{
// Trigger specific action
$action = $this->request->variable('action', '');
if (in_array($action, array('add', 'edit', 'enable', 'disable', 'delete')))
{
$this->{'action_' . $action}();
}
else
{
// Otherwise default to this
$this->list_ads();
}
}
/**
* Add an advertisement
*
* @return void
*/
protected function action_add()
{
$action = $this->get_submitted_action();
if ($action !== false)
{
$this->data = $this->input->get_form_data();
$this->{$action}();
$this->helper->assign_data($this->data, $this->input->get_errors());
}
else
{
$this->helper->assign_locations();
$this->helper->assign_groups();
}
// Set output vars for display in the template
$this->template->assign_vars(array(
'S_ADD_AD' => true,
'U_BACK' => $this->u_action,
'U_ACTION' => "{$this->u_action}&action=add",
'PICKER_DATE_FORMAT' => ext::DATE_FORMAT,
'U_FIND_USERNAME' => $this->helper->get_find_username_link(),
'U_ENABLE_VISUAL_DEMO' => $this->controller_helper->route('phpbb_ads_visual_demo', array('action' => 'enable')),
));
}
/**
* Edit an advertisement
*
* @return void
*/
protected function action_edit()
{
$ad_id = $this->request->variable('id', 0);
$action = $this->get_submitted_action();
if ($action !== false)
{
$this->data = $this->input->get_form_data();
$this->{$action}();
}
else
{
$this->data = $this->manager->get_ad($ad_id);
if (empty($this->data))
{
$this->error('ACP_AD_DOES_NOT_EXIST');
}
// Load ad template locations
$this->data['ad_locations'] = $this->manager->get_ad_locations($ad_id);
}
// Set output vars for display in the template
$this->template->assign_vars(array(
'S_EDIT_AD' => true,
'EDIT_ID' => $ad_id,
'U_BACK' => $this->u_action,
'U_ACTION' => "{$this->u_action}&action=edit&id=$ad_id",
'PICKER_DATE_FORMAT' => ext::DATE_FORMAT,
'U_FIND_USERNAME' => $this->helper->get_find_username_link(),
'U_ENABLE_VISUAL_DEMO' => $this->controller_helper->route('phpbb_ads_visual_demo', array('action' => 'enable')),
));
$this->helper->assign_data($this->data, $this->input->get_errors());
}
/**
* Enable an advertisement
*
* @return void
*/
protected function action_enable()
{
$this->ad_enable(true);
}
/**
* Disable an advertisement
*
* @return void
*/
protected function action_disable()
{
$this->ad_enable(false);
}
/**
* Delete an advertisement
*
* @return void
*/
protected function action_delete()
{
$ad_id = $this->request->variable('id', 0);
if ($ad_id)
{
if (confirm_box(true))
{
// Get ad data so that we can log ad name
$ad_data = $this->manager->get_ad($ad_id);
// Delete ad and it's template locations
$this->manager->delete_ad_locations($ad_id);
$success = $this->manager->delete_ad($ad_id);
$this->toggle_permission($ad_data['ad_owner']);
// Only notify user on error or if not ajax
if (!$success)
{
$this->error('ACP_AD_DELETE_ERRORED');
}
else
{
$this->helper->log('DELETE', $ad_data['ad_name']);
if (!$this->request->is_ajax())
{
$this->success('ACP_AD_DELETE_SUCCESS');
}
}
}
else
{
confirm_box(false, $this->language->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
'id' => $ad_id,
'i' => $this->request->variable('i', ''),
'mode' => $this->request->variable('mode', ''),
'action' => 'delete',
)));
// When you don't confirm deleting ad
$this->list_ads();
}
}
}
/**
* Display the list of all ads
*
* @return void
*/
protected function list_ads()
{
foreach ($this->manager->get_all_ads() as $row)
{
$ad_enabled = (int) $row['ad_enabled'];
$ad_expired = $this->helper->is_expired($row);
if ($ad_expired && $ad_enabled)
{
$ad_enabled = 0;
$this->manager->update_ad($row['ad_id'], array('ad_enabled' => 0));
}
$this->template->assign_block_vars($ad_expired ? 'expired' : 'ads', array(
'NAME' => $row['ad_name'],
'PRIORITY' => $row['ad_priority'],
'START_DATE' => $row['ad_start_date'],
'END_DATE' => $row['ad_end_date'],
'VIEWS' => $row['ad_views'],
'CLICKS' => $row['ad_clicks'],
'VIEWS_LIMIT' => $row['ad_views_limit'],
'CLICKS_LIMIT' => $row['ad_clicks_limit'],
'S_EXPIRED' => $ad_expired,
'S_ENABLED' => $ad_enabled,
'U_ENABLE' => $this->u_action . '&action=' . ($ad_enabled ? 'disable' : 'enable') . '&id=' . $row['ad_id'],
'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['ad_id'],
'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['ad_id'],
));
}
// Set output vars for display in the template
$this->template->assign_vars(array(
'U_ACTION_ADD' => $this->u_action . '&action=add',
'S_VIEWS_ENABLED' => $this->config['phpbb_ads_enable_views'],
'S_CLICKS_ENABLED' => $this->config['phpbb_ads_enable_clicks'],
));
}
/**
* Get what action user wants to do with the form.
* Possible options are:
* - preview ad code
* - upload banner to display in an ad code
* - analyse ad code
* - submit form (either add or edit an ad)
*
* @return string|false Action name or false when no action was submitted
*/
protected function get_submitted_action()
{
$actions = array('preview', 'upload_banner', 'analyse_ad_code', 'submit_add', 'submit_edit');
foreach ($actions as $action)
{
if ($this->request->is_set_post($action))
{
return $action;
}
}
return false;
}
/**
* Enable/disable an advertisement
*
* @param bool $enable Enable or disable the advertisement?
* @return void
*/
protected function ad_enable($enable)
{
$ad_id = $this->request->variable('id', 0);
$success = $this->manager->update_ad($ad_id, array(
'ad_enabled' => (int) $enable,
));
// If AJAX was used, show user a result message
if ($this->request->is_ajax())
{
$json_response = new \phpbb\json_response;
$json_response->send(array(
'text' => $this->language->lang($enable ? 'ENABLED' : 'DISABLED'),
'title' => $this->language->lang('AD_ENABLE_TITLE', (int) $enable),
));
}
// Otherwise, show traditional infobox
if ($success)
{
$this->success($enable ? 'ACP_AD_ENABLE_SUCCESS' : 'ACP_AD_DISABLE_SUCCESS');
}
else
{
$this->error($enable ? 'ACP_AD_ENABLE_ERRORED' : 'ACP_AD_DISABLE_ERRORED');
}
}
/**
* Submit action "preview".
* Prepare advertisement preview.
*
* @return void
*/
protected function preview()
{
$this->template->assign_var('PREVIEW', htmlspecialchars_decode($this->data['ad_code'], ENT_COMPAT));
}
/**
* Submit action "upload_banner".
* Upload banner and append it to the ad code.
*
* @return void
*/
protected function upload_banner()
{
$this->data['ad_code'] = $this->input->banner_upload($this->data['ad_code']);
}
/**
* Submit action "analyse_ad_code".
* Upload banner and append it to the ad code.
*
* @return void
*/
protected function analyse_ad_code()
{
$this->analyser->run($this->data['ad_code']);
}
/**
* Submit action "submit_add".
* Add new ad.
*
* @return void
*/
protected function submit_add()
{
if (!$this->input->has_errors())
{
$ad_id = $this->manager->insert_ad($this->data);
$this->toggle_permission($this->data['ad_owner']);
$this->manager->insert_ad_locations($ad_id, $this->data['ad_locations']);
$this->helper->log('ADD', $this->data['ad_name']);
$this->success('ACP_AD_ADD_SUCCESS');
}
}
/**
* Submit action "submit_edit".
* Edit ad.
*
* @return void
*/
protected function submit_edit()
{
$ad_id = $this->request->variable('id', 0);
if ($ad_id && !$this->input->has_errors())
{
$old_data = $this->manager->get_ad($ad_id);
$success = $this->manager->update_ad($ad_id, $this->data);
if ($success)
{
// Only update permissions when update was successful
$this->toggle_permission($old_data['ad_owner']);
$this->toggle_permission($this->data['ad_owner']);
// Only insert new ad locations to DB when ad exists
$this->manager->delete_ad_locations($ad_id);
$this->manager->insert_ad_locations($ad_id, $this->data['ad_locations']);
$this->helper->log('EDIT', $this->data['ad_name']);
$this->success('ACP_AD_EDIT_SUCCESS');
}
$this->error('ACP_AD_DOES_NOT_EXIST');
}
}
/**
* Print success message.
*
* @param string $msg Message lang key
*/
protected function success($msg)
{
trigger_error($this->language->lang($msg) . adm_back_link($this->u_action));
}
/**
* Print error message.
*
* @param string $msg Message lang key
*/
protected function error($msg)
{
trigger_error($this->language->lang($msg) . adm_back_link($this->u_action), E_USER_WARNING);
}
/**
* Try to remove or add permission to see UCP module.
* Permission is only removed when user has no more ads.
* Permission is only added when user has at least one ad.
*
* @param int $user_id User ID to try to remove permission
*
* @return void
*/
protected function toggle_permission($user_id)
{
if ($user_id)
{
$has_ads = count($this->manager->get_ads_by_owner($user_id)) !== 0;
$this->auth_admin->acl_set('user', 0, $user_id, array('u_phpbb_ads' => (int) $has_ads));
}
}
}