Skip to content

Instantly share code, notes, and snippets.

@luniki
Created December 8, 2011 13:26
Show Gist options
  • Save luniki/1446985 to your computer and use it in GitHub Desktop.
Save luniki/1446985 to your computer and use it in GitHub Desktop.
Button-StEP RC1
<?php
/*
* Copyright (c) 2011 mlunzena@uos.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
namespace Studip;
/**
* Represents an abstract interactable element.
*/
abstract class Interactable
{
public $label, $attributes;
/**
* Constructs a new button.
*
* @param string $label the label of the button
* @param array $attributes the attributes of the button element
*/
function __construct($label, $attributes)
{
$this->label = $label;
$this->attributes = $attributes;
}
/**
* Magic method (triggered when invoking inaccessible methods in a static
* context) used to dynamically create a button with an additional CSS
* class. This works for every static method call matching: /^get(.+)/
* The matched group is used as CSS class for the button.
*
* @code
* echo Button::getSubmit();
*
* # => <button ... class="submit">...
* @endcode
*
* @param string $name name of the method being called
* @param array $args enumerated array containing the parameters
* passed to the $name'ed method
*
* @return Button returns a Button, if $name =~ /^get/
* @throws throws a BadMethodCallException if $name does not
* match
*/
public static function __callStatic($name, $args)
{
# only trigger, if $name =~ /^get/ and at least using $label
if (substr($name, 0, 3) === 'get') {
# instantiate button from arguments
$button = call_user_func_array(array(get_called_class(), 'get'), $args);
# but customize with class from $name:
$class = self::hyphenate(substr($name, 3));
# a.) set name unless set
if (!is_string(@$args[1])) {
$button->attributes['name'] = $class;
}
# b.) set/append CSS class
if (array_key_exists('class', $button->attributes)) {
$button->attributes['class'] .= " $class";
} else {
$button->attributes['class'] = $class;
}
return $button;
}
# otherwise bail out
throw new BadMethodCallException();
}
static function get($label = NULL, $trait = NULL, $attributes = array())
{
$argc = func_num_args();
// if label is empty, use default
$label = $label ?: _('ok');
// if there are two parameters, there are two cases:
// 1.) label and name OR
// 2.) label and attributes
//
// in the latter case, use parameter $trait as attributes
// and use the default for name
if ($argc === 2 && is_array($trait)) {
list($attributes, $trait) = array($trait, NULL);
}
$button = new static($label, $attributes);
$button->initialize($label, $trait, $attributes);
return $button;
}
abstract function initialize($label, $trait, $attributes);
static function getAccept($label = NULL, $name = NULL, $attributes = array())
{
$args = func_num_args() ? func_get_args() : array('übernehmen');
return self::__callStatic(__FUNCTION__, $args);
}
static function getCancel($label = NULL, $name = NULL, $attributes = array())
{
$args = func_num_args() ? func_get_args() : array('abbrechen');
return self::__callStatic(__FUNCTION__, $args);
}
private static function hyphenate($word)
{
return strtolower(preg_replace('/(?<=\w)([A-Z])/', '-\\1', $word));
}
}
<?php
/*
* Copyright (c) 2011 mlunzena@uos.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
namespace Studip;
require('Interactable.class.php');
/**
* Represents an HTML button element.
*/
class Button extends Interactable
{
/**
* Easy factory method to get a Button instance.
* All parameters are optional.
*
* @code
* echo Button::get();
* # => <button type="submit" name="ok">ok</button>
*
* echo Button::get('yes')
* # => <button type="submit" name="yes">yes</button>
*
* echo Button::get('yes', 'aName')
* # => <button type="submit" name="aName">yes</button>
*
* echo Button::get('yes', array('a' => 1, 'b' => 2))
* # => <button type="submit" a="1" b="2" name="yes">yes</button>
*
* echo Button::get('yes', 'aName', array('a' => 1, 'b' => 2)),
* # => <button type="submit" a="1" b="2" name="aName">yes</button>
* @endcode
*
* @param string $label the label of the button
* @param string $name the name attribute of the button element
* @param array $attributes the attributes of the button element
*/
function initialize($label, $name, $attributes)
{
$this->attributes['name'] = $name ?: $this->label;
}
/**
* @return returns a HTML representation of this buton.
*/
function __toString()
{
$attributes = array();
ksort($this->attributes);
foreach ($this->attributes as $k => $v) {
$attributes[] = sprintf(' %s="%s"', $k, htmlReady($v));
}
return sprintf('<button type="submit"%s>%s</button>',
join('', $attributes),
htmlReady($this->label));
}
}
@require(dirname(__FILE__) . '/../bootstrap.php');
require('vendor/simpletest/autorun.php');
class ButtonTest extends \UnitTestCase
{
function testGet()
{
$this->assertEqual('' . Button::get(), '<button type="submit" name="ok">ok</button>');
}
function testGetWithLabel()
{
$this->assertEqual('' . Button::get('yes'), '<button type="submit" name="yes">yes</button>');
}
function testGetWithLabelAndString()
{
$this->assertEqual('' . Button::get('yes', 'aName'), '<button type="submit" name="aName">yes</button>');
}
function testGetWithLabelAndArray()
{
$this->assertEqual('' . Button::get('yes', array('a' => 1, 'b' => 2)),
'<button type="submit" a="1" b="2" name="yes">yes</button>');
}
function testGetWithLabelNameAndArray()
{
$this->assertEqual('' . Button::get('yes', 'aName', array('a' => 1, 'b' => 2)),
'<button type="submit" a="1" b="2" name="aName">yes</button>');
}
function testGetAccept()
{
$this->assertEqual('' . Button::getAccept(),
'<button type="submit" class="accept" name="accept">&uuml;bernehmen</button>');
}
function testGetCancel()
{
$this->assertEqual('' . Button::getCancel(),
'<button type="submit" class="cancel" name="cancel">abbrechen</button>');
}
function testGetPreOrder()
{
$this->assertEqual('' . Button::getPreOrder(),
'<button type="submit" class="pre-order" name="pre-order">ok</button>');
}
function testGetWithInsaneArguments()
{
$this->assertEqual('' . Button::get('>ok<', 'm&m', array('mad' => '<S>tu"ff')),
'<button type="submit" mad="&lt;S&gt;tu&quot;ff" name="m&amp;m">&gt;ok&lt;</button>');
}
}
<?php
/*
* Copyright (c) 2011 aklassen@uos.de
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
namespace Studip;
require('Interactable.class.php');
/**
* Represents an HTML link element.
*/
class LinkButton extends Interactable
{
function initialize($label, $url, $attributes)
{
$this->attributes['href'] = $url ?: @\URLHelper::getURL();
}
/**
* @return returns a HTML representation of this buton.
*/
function __toString()
{
// add "button" to attribute "class"
@$this->attributes["class"] .= " button";
$attributes = array();
ksort($this->attributes);
foreach ($this->attributes as $k => $v) {
$attributes[] = sprintf(' %s="%s"', $k, htmlReady($v));
}
// TODO: URLHelper...?!
return sprintf('<a%s>%s</a>',
join('', $attributes),
htmlReady($this->label));
}
}
@require(dirname(__FILE__) . '/../bootstrap.php');
require('vendor/simpletest/autorun.php');
class ButtonTest extends \UnitTestCase
{
function testGet()
{
$this->assertEqual('' . LinkButton::get(), '<a class="button" href="?">ok</a>');
}
function testGetWithLabel()
{
$this->assertEqual('' . LinkButton::get('yes'), '<a class="button" href="?">yes</a>');
}
function testGetWithLabelAndUrl()
{
$this->assertEqual('' . LinkButton::get('yes', 'http://example.net'), '<a class="button" href="http://example.net">yes</a>');
}
function testGetWithLabelAndArray()
{
$this->assertEqual('' . LinkButton::get('yes', array('a' => 1, 'b' => 2)),
'<a a="1" b="2" class="button" href="?">yes</a>');
}
function testGetWithLabelUrlAndArray()
{
$this->assertEqual('' . LinkButton::get('yes', 'http://example.net', array('a' => 1, 'b' => 2)),
'<a a="1" b="2" class="button" href="http://example.net">yes</a>');
}
function testGetAccept()
{
$this->assertEqual('' . LinkButton::getAccept(),
'<a class="accept button" href="?" name="accept">&uuml;bernehmen</a>');
}
function testGetCancel()
{
$this->assertEqual('' . LinkButton::getCancel(),
'<a class="cancel button" href="?" name="cancel">abbrechen</a>');
}
function testGetPreOrder()
{
$this->assertEqual('' . LinkButton::getPreOrder(),
'<a class="pre-order button" href="?" name="pre-order">ok</a>');
}
function testGetWithInsaneArguments()
{
$this->assertEqual('' . LinkButton::get('>ok<', 'http://example.net?m=&m=', array('mad' => '<S>tu"ff')),
'<a class="button" href="http://example.net?m=&amp;m=" mad="&lt;S&gt;tu&quot;ff">&gt;ok&lt;</a>');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment