botcha_form.controller.inc in BOTCHA Spam Prevention 7.2
Same filename and directory in other branches
Controller layer of the BotchaForm objects.
File
controller/botcha_form.controller.incView source
<?php
/**
* @file
* Controller layer of the BotchaForm objects.
*/
/**
* Special class to abstract operations with form_id. Casual usage is getting
* all recipe books by form_id. It could be done by adding one more method to
* Botcha (such as "getRecipebookByFormId") but in long-time perspective
* it is counter-intuitive to extend our model by this way.
* The way it is done here is as follows:
* Botcha::getForm($form_id)
* ->getRecipebook();
* It looks like additional layer of abstraction after DatabaseAbstractionLayer.
* It helps us to get necessary data - while we don't have to repeat ourselves
* in many places, writing queries to the database. All logic is hidden under
* this simple interface: getForm, getRecipebook, getRecipe.
*/
abstract class BotchaFormAbstract {
protected $recipebook;
protected function __construct($form_id) {
$this->id = $form_id;
}
/**
* @todo BotchaForm getForm Description.
* @param string $form_id
* @param boolean $create
* Determines should we construct new form or return NULL if it does not exist.
* @return BotchaForm
*/
public static function getForm($form_id, $create = TRUE) {
$none = TRUE;
// Respect form exceptions (done by forbidden_forms recipe book).
//if (!in_array($form_id, array('user_login', 'user_login_block', 'update_script_selection_form'))) {
$form = BotchaFormModel::getForm($form_id);
if ($form || $create) {
$none = FALSE;
}
//}
$botcha_form = $none ? new BotchaFormNone($form_id) : new BotchaForm($form_id);
return $botcha_form;
}
public function setRecipebook($rbid) {
$this->recipebook = $rbid;
// Save changed state.
Botcha::setForm($this);
return $this;
}
function unsetRecipebook() {
unset($this->recipebook);
// Save changed state.
Botcha::setForm($this);
return $this;
}
/**
* @todo BotchaForm getRecipebook Description.
* @return BotchaRecipebook
*/
public function getRecipebook() {
if (empty($this->recipebook)) {
$rbs = BotchaModel::getRecipebooksForms(array(
'mode' => 'recipebook',
'forms' => $this->id,
));
// In fact there is not more than 1 item.
$this->recipebook = !empty($rbs) ? current($rbs) : 'none';
}
return Botcha::getRecipebook($this->recipebook, FALSE);
}
public function isEnabled() {
$form_id = $this->id;
$isEnabled = variable_get("botcha_enabled_{$form_id}", 0);
return $isEnabled;
}
public function setEnabled($enabled) {
$form_id = $this->id;
// Cast to boolean first.
$enabled = (bool) $enabled;
// Cast to integer.
$enabled = (int) $enabled;
variable_set("botcha_enabled_{$form_id}", $enabled);
return $this;
}
public function addAdminLinks(&$form) {
$form_id = $form['form_id']['#value'];
if (variable_get('botcha_administration_mode', FALSE) && user_access('administer BOTCHA settings') && (arg(0) != 'admin' || variable_get('botcha_allow_on_admin_pages', FALSE) || $form_id == 'user_register')) {
// Add BOTCHA administration tools.
$botcha_element = $this
->createAdminLinksFieldset($form_id);
// Get placement in form and insert in form.
// @todo BotchaRecipebook isApplicable Make away with a dependency from botcha.inc.
$botcha_placement = _botcha_get_botcha_placement($form_id, $form);
_botcha_insert_botcha_element($form, $botcha_placement, $botcha_element);
}
}
protected function createAdminLinksFieldset($form_id) {
// For administrators: show BOTCHA info and offer link to configure it.
return array(
'#type' => 'fieldset',
'#title' => t('BOTCHA'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
// @todo Abstract it.
'#attributes' => array(
'class' => array(
'botcha-admin-links',
),
),
);
}
// @todo ?Should we separate BotchaForm and BotchaFormAbstract?
public function save() {
// Save our form to cache.
Botcha::setForm($this);
// Save form to DB.
BotchaFormModel::save($this);
// Clean session to fetch new values.
Botcha::clean();
return $this;
}
public function delete() {
// Save our form to cache.
Botcha::unsetForm($this);
// Save form to DB.
BotchaFormModel::delete($this);
// Clean session to fetch new values.
Botcha::clean();
}
}
class BotchaForm extends BotchaFormAbstract {
protected function createAdminLinksFieldset($form_id) {
$botcha_element = parent::createAdminLinksFieldset($form_id);
$recipebook = Botcha::getForm($form_id, FALSE)
->getRecipebook();
$botcha_element['#title'] = t('BOTCHA: protection enabled (@recipebook recipe book)', array(
'@recipebook' => $recipebook->id,
));
$botcha_element['#description'] = t('Untrusted users will have form %form_id protected by BOTCHA (!recipebook_settings, !general_settings).', array(
'%form_id' => $form_id,
'!recipebook_settings' => l(t('Recipe book settings'), Botcha::BOTCHA_ADMIN_PATH . "/recipebook/{$recipebook->id}"),
'!general_settings' => l(t('General BOTCHA settings'), Botcha::BOTCHA_ADMIN_PATH),
));
$botcha_element['protection'] = array(
'#type' => 'item',
'#title' => t('Enabled protection'),
'#markup' => t('Form is protected by "@recipebook" recipe book (!edit, !disable)', array(
//'#value' => t('Form is protected by "@recipebook" recipe book (!edit, !disable)', array(
'@recipebook' => $recipebook->id,
'!edit' => l(t('edit'), Botcha::BOTCHA_ADMIN_PATH . "/form/{$form_id}", array(
'query' => drupal_get_destination(),
'html' => TRUE,
)),
'!disable' => l(t('disable'), Botcha::BOTCHA_ADMIN_PATH . "/form/{$form_id}/disable", array(
'query' => drupal_get_destination(),
'html' => TRUE,
)),
)),
);
return $botcha_element;
}
}
/**
* Dummy class, created for data consistency and for interface unifying.
* When there is no form, this class is used as a handler.
* It has no logic at all - by design.
*/
class BotchaFormNone extends BotchaForm {
// @todo Refactor this since it is duplication.
public function __construct($form_id = NULL) {
$this->id = !empty($form_id) ? $form_id : 'none';
}
public function getRecipebook() {
return new BotchaRecipebookNone();
}
public function addAdminLinks(&$form) {
$form_id = $form['form_id']['#value'];
// Apply only to allowed forms.
// @todo Move it to new abstraction: form exceptions.
if (!in_array($form_id, array(
'update_script_selection_form',
'user_login',
'user_login_block',
))) {
parent::addAdminLinks($form);
}
}
protected function createAdminLinksFieldset($form_id) {
$botcha_element = parent::createAdminLinksFieldset($form_id);
$botcha_element['#title'] = t('BOTCHA: no protection enabled');
$botcha_element['add_botcha'] = array(
// @todo Abstract it.
'#markup' => l(t('Add BOTCHA protection on form'), Botcha::BOTCHA_ADMIN_PATH . "/form/add", array(
'query' => array_merge(drupal_get_destination(), array(
'botcha_form_id' => $form_id,
)),
'html' => TRUE,
)),
);
return $botcha_element;
}
public function save() {
Botcha::unsetForm($this);
// Save form to DB.
BotchaFormModel::save($this);
// Clean session to fetch new values.
Botcha::clean();
}
}
Classes
Name | Description |
---|---|
BotchaForm | |
BotchaFormAbstract | Special class to abstract operations with form_id. Casual usage is getting all recipe books by form_id. It could be done by adding one more method to Botcha (such as "getRecipebookByFormId") but in long-time perspective it is… |
BotchaFormNone | Dummy class, created for data consistency and for interface unifying. When there is no form, this class is used as a handler. It has no logic at all - by design. |