Skip to content

Instantly share code, notes, and snippets.

@notbrain
Last active December 14, 2015 07:19
Show Gist options
  • Save notbrain/5050157 to your computer and use it in GitHub Desktop.
Save notbrain/5050157 to your computer and use it in GitHub Desktop.
<?php
class featureButtonSlotActions extends BaseaButtonSlotActions {
/**
* Image association is handled by a separate action
* @param sfRequest $request
* @return mixed
*/
public function executeImage(sfRequest $request)
{
if ($request->getParameter('aMediaCancel'))
{
return $this->redirectToPage();
}
$this->logMessage("====== in featureButtonSlotActions::executeImage", "info");
$this->editSetup();
$item = Doctrine::getTable('aMediaItem')->find($request->getParameter('aMediaId'));
$this->slot->unlink('MediaItems');
// It's not a bug to have no media item selected - allow the trashcan to work to remove it
if ($item && ($item->type === 'image'))
{
$this->slot->link('MediaItems', array($item->id));
}
return $this->editSave();
}
/**
* Use the edit view for the URL (and any other well-behaved fields that may arise)
* @param sfRequest $request
* @return mixed
*/
public function executeEdit(sfRequest $request)
{
$this->logMessage("====== in featureButtonSlotActions::executeEdit", "info");
$this->editSetup();
// Work around FCK's incompatibility with AJAX and bracketed field names
// (it insists on making the ID bracketed too which won't work for AJAX)
// Don't forget, there's a CSRF field out there too. We need to grep through
// the submitted fields and get all of the relevant ones, reinventing what
// PHP's bracket syntax would do for us if FCK were compatible with it
$values = $request->getParameterHolder()->getAll();
$value = array();
foreach ($values as $k => $v)
{
if (preg_match('/^slot-form-' . $this->id . '-(.*)$/', $k, $matches))
{
$value[$matches[1]] = $v;
}
}
if ($this->getOption('editLink', null) !== false)
{
// Trim whitespace off the front & end of the URL to avoid failing validation on a perfectly acceptable URL
$value['url'] = trim($value['url']);
}
$this->form = new featureButtonSlotEditForm($this->id, $this->options);
$this->form->bind($value);
if ($this->form->isValid())
{
if ($this->getOption('editLink', null) !== false)
{
$url = $this->form->getValue('url');
}
$value = $this->slot->getArrayValue();
if ($this->getOption('editLink', null) !== false)
{
$value['url'] = $url;
}
$value['title'] = $this->form->getValue('title');
$value['description'] = $this->form->getValue('description');
$this->slot->setArrayValue($value);
$result = $this->editSave();
return $result;
}
else
{
// Makes $this->form available to the next iteration of the
// edit view so that validation errors can be seen
return $this->editRetry();
}
}
}
<?php
class featureButtonSlotComponents extends BaseaButtonSlotComponents {
protected function getButtonMedia()
{
// We are going to return the media in both Normal and Edit View
// Backwards compatibility with pkContextCMS button slots that the data migration task missed
if (!count($this->slot->MediaItems))
{
$value = $this->slot->getArrayValue();
if (isset($value['image']))
{
$mediaItem = Doctrine::getTable('aMediaItem')->find($value['image']->id);
if ($mediaItem)
{
$this->slot->MediaItems[] = $mediaItem;
}
}
}
if (!count($this->slot->MediaItems))
{
$this->item = false;
$this->itemId = false;
}
else
{
$this->item = $this->slot->MediaItems[0];
$this->itemId = $this->item->id;
$this->dimensions = aDimensions::constrain(
$this->item->width,
$this->item->height,
$this->item->format,
array("width" => $this->options['width'],
"height" => $this->options['flexHeight'] ? false : $this->options['height'],
"resizeType" => $this->options['resizeType']));
if (($this->options['maxHeight'] !== false) && ($this->dimensions['height'] > $this->options['maxHeight']))
{
$this->dimensions = aDimensions::constrain(
$this->item->width,
$this->item->height,
$this->item->format,
array("width" => false,
"height" => $this->options['maxHeight'],
"resizeType" => $this->options['resizeType']));
}
$this->embed = $this->item->getEmbedCode($this->dimensions['width'], $this->dimensions['height'], $this->dimensions['resizeType'], $this->dimensions['format'], false, 'opaque', false, array('alt' => strlen($this->options['title']) ? $this->options['title'] : ''));
}
}
/**
* DOCUMENT ME
*/
protected function setupOptions()
{
$this->options['constraints'] = $this->getOption('constraints', array());
$this->options['width'] = $this->getOption('width', 440);
$this->options['height'] = $this->getOption('height', false);
$this->options['resizeType'] = $this->getOption('resizeType', 's');
$this->options['flexHeight'] = $this->getOption('flexHeight', true);
$this->options['maxHeight'] = $this->getOption('maxHeight', false);
$this->options['title'] = $this->getOption('title', false);
$this->options['description'] = $this->getOption('description', true);
$this->options['link'] = $this->getOption('link', false);
$this->options['url'] = $this->getOption('link', false);
$this->options['rollover'] = $this->getOption('rollover', true);
$this->options['defaultImage'] = $this->getOption('defaultImage', false);
$this->options['itemTemplate'] = $this->getOption('itemTemplate', 'default');
$this->options['image'] = $this->getOption('image', true);
}
/**
* DOCUMENT ME
*/
public function executeEditView()
{
$this->setup();
$this->setupOptions();
$this->options['width'] = 160;
$this->options['height'] = 160;
// Careful, don't clobber a form object provided to us with validation errors
// from an earlier pass
if (!isset($this->form))
{
// $this->logMessage("HERE --- ID = " . $this->id, "info");
$this->form = new featureButtonSlotEditForm($this->id, $this->options);
$value = $this->slot->getArrayValue();
if (isset($value['url']))
{
$this->form->setDefault('url', $value['url']);
}
else
{
$this->form->setDefault('url', $this->getOption('link'));
}
if (isset($value['title']))
{
$this->form->setDefault('title', $value['title']);
}
else
{
// Careful, just plain true is a valid setting for this option
$title = $this->getOption('title');
if (strlen($title) && ($title !== true))
{
$this->form->setDefault('title', $title);
}
}
if (isset($value['description']))
{
$this->form->setDefault('description', $value['description']);
}
}
$this->getButtonMedia();
}
/**
* DOCUMENT ME
*/
public function executeNormalView()
{
// Mostly identical to aImage, but we have the URL to contend with too
$this->setup();
$this->setupOptions();
// Behave well if it's not set yet!
$data = $this->slot->getArrayValue();
// If there is a URL stored in the slot
// Use that URL (instead of the supplied link slot)
if (isset($data['url']))
{
$this->options['url'] = $data['url'];
}
// If the title is TRUE or a String, check if there's a title set in the slot $data
// IF NOT, THEN check if there's a string set in the slot options
if ($this->options['title'])
{
if (isset($data['title']))
{
$this->options['title'] = $data['title'];
}
else
{
$this->options['title'] = ($this->options['title'] === true) ? false : $this->options['title'];
}
}
if ($this->options['description'])
{
if (isset($data['description'])) {
$this->options['description'] = $data['description'];
}
else
{
$this->options['description'] = false;
}
}
$this->getButtonMedia();
}
}
<?php
class featureButtonSlotEditForm extends BaseaButtonForm
{
protected $id;
protected $soptions;
/**
* PARAMETERS ARE REQUIRED, no-parameters version is strictly to satisfy i18n-update
* @param mixed $id
* @param mixed $soptions
*/
public function __construct($id = 1, $soptions = array())
{
$this->id = $id;
$this->soptions = $soptions;
$soptions['class'] = 'featureButtonSlot';
$this->allowedTags = $this->consumeSlotOption('allowed-tags');
$this->allowedAttributes = $this->consumeSlotOption('allowed-attributes');
$this->allowedStyles = $this->consumeSlotOption('allowed-styles');
/*
__
/ /_ ___ ________
/ __ \/ _ \/ ___/ _ \
/ / / / __/ / / __/
/_/ /_/\___/_/ \___/
*/
// BY DEFAULT THIS CONSTRUCTOR HAS NO ARGUMENTS!
//parent::__construct();
parent::__construct($id, $options);
}
/**
* DOCUMENT ME
* @param mixed $s
* @return mixed
*/
protected function consumeSlotOption($s)
{
if (isset($this->soptions[$s]))
{
$v = $this->soptions[$s];
unset($this->soptions[$s]);
return $v;
}
else
{
return null;
}
}
/**
* DOCUMENT ME
*/
public function configure()
{
$widgetOptions = array();
$widgetOptions['tool'] = 'Sidebar';
$tool = $this->consumeSlotOption('tool');
if (!is_null($tool))
{
$widgetOptions['tool'] = $tool;
}
$this->setWidgets(array(
'description' => new aWidgetFormRichTextarea($widgetOptions, $this->soptions),
'url' => new sfWidgetFormInputText(array(), array('class' => 'featureButtonSlot')),
'title' => new sfWidgetFormInputText(array(), array('class' => 'featureButtonSlot'))
));
$this->setValidators(array(
'description' => new sfValidatorHtml(array('required' => false, 'allowed_tags' => $this->allowedTags, 'allowed_attributes' => $this->allowedAttributes, 'allowed_styles' => $this->allowedStyles)),
'url' => new sfValidatorAnd(array(
// www.foo.bar => http://www.foo.bar
new sfValidatorCallback(array('callback' => array($this, 'validateLazyUrl'))),
// Must be a valid URL to go past this stage
new sfValidatorCallback(array('callback' => array($this, 'validateUrl'))),
)),
'title' => new sfValidatorString(array('required' => false))
));
$editLink = $this->consumeSlotOption('editLink');
if ($editLink === false)
{
unset($this['url']);
}
// Ensures unique IDs throughout the page. Hyphen between slot and form to please our CSS
$this->widgetSchema->setNameFormat('slot-form-' . $this->id . '-%s');
// You don't have to use our form formatter, but it makes things nice
$this->widgetSchema->setFormFormatterName('aAdmin');
$this->widgetSchema->getFormFormatter()->setTranslationCatalogue('apostrophe');
}
/**
* Add missing http:
* @param mixed $validator
* @param mixed $value
* @return mixed
*/
public function validateLazyUrl($validator, $value)
{
if (preg_match('/^[\w\+-]+\./', $value))
{
return 'http://' . $value;
}
return $value;
}
/**
* DOCUMENT ME
* @param mixed $validator
* @param mixed $value
* @return mixed
*/
public function validateUrl($validator, $value)
{
$url = $value;
// sfValidatorUrl doesn't accept mailto, deal with local URLs at all, etc.
// Let's take a stab at a more forgiving approach. Also, if the URL
// begins with the site's prefix, turn it back into a local URL just before
// save time for better data portability. TODO: let this stew a bit then
// turn it into a validator and use a form here
$prefix = sfContext::getInstance()->getRequest()->getUriPrefix();
if (substr($url, 0, 1) === '/')
{
$url = "$prefix$url";
}
// Borrowed and extended from sfValidatorUrl
if (!preg_match(
'~^
(
(https?|ftps?):// # http or ftp (+SSL)
(
[\w\-\.]+ # a domain name (tolerate intranet short names)
| # or
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # a IP address
)
(:[0-9]+)? # a port (optional)
(/?|/\S+) # a /, nothing or a / with something
|
mailto:\S+
)
$~ix', $url))
{
throw new sfValidatorError($validator, 'invalid', array('value' => $url));
}
else
{
// Convert URLs back to local if they have the site's prefix
if (substr($url, 0, strlen($prefix)) === $prefix)
{
$url = substr($url, strlen($prefix));
}
}
return $url;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment