Skip to content

Instantly share code, notes, and snippets.

@fivestar
Created October 1, 2010 09:42
Show Gist options
  • Save fivestar/605991 to your computer and use it in GitHub Desktop.
Save fivestar/605991 to your computer and use it in GitHub Desktop.
<?php
/**
* blog actions.
*
* @login_required
*/
class blogActions extends sfAnnotationActions
{
/**
* @login_required
*/
public function executeIndex(sfWebRequest $request)
{
$this->posts = Doctrine::getTable('Post')
->createQuery('a')
->execute();
}
/**
* @login_required([admin, foo, bar])
*/
public function executeNew(sfWebRequest $request)
{
$this->form = new PostForm();
}
}
<?php
require_once '/home/fivestar/projects/vendor/symfony-project.org/branches/1.4/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();
class ProjectConfiguration extends sfProjectConfiguration
{
protected $annotationCache;
public function setup()
{
$this->enablePlugins('sfDoctrinePlugin');
}
public function getAnnotationCache()
{
if (!isset($this->annotationCache)) {
$this->annotationCache = new sfAPCCache();
}
return $this->annotationCache;
}
}
<?php
/**
* Annotation actions.
*
* @author Katsuhiro Ogawa <[email protected]>
* @licence MIT Licence
*/
class sfAnnotationActions extends sfActions
{
public function initialize($context, $moduleName, $actionName)
{
sfComponent::initialize($context, $moduleName, $actionName);
$this->setSecurityConfiguration($this->parseSecurityAnnotations());
}
protected function parseSecurityAnnotations()
{
if (method_exists($this->context->getConfiguration(), 'getAnnotationCache')) {
$cache = $this->context->getConfiguration()->getAnnotationCache();
if ($cache->has('actions.'.get_class($this))) {
$cachedAnnotations = $cache->get('actions.'.get_class($this));
if ($cachedAnnotations) {
return $cachedAnnotations;
}
}
}
$securityConfiguration = array();
$class = new ReflectionObject($this);
$securityConfiguration['all'] = $this->extractSecurityConfiguration($class->getDocComment());
$methods = $class->getMethods();
foreach ($methods as $method) {
if (0 === strpos($method->getName(), 'execute')) {
$actionName = strtolower(substr($method->getName(), 7));
$securityConfiguration[$actionName] = $this->extractSecurityConfiguration($method->getDocComment());
}
}
if (isset($cache)) {
$cache->set('actions.'.get_class($this), $securityConfiguration);
}
return $securityConfiguration;
}
protected function extractSecurityConfiguration($comment)
{
$config = array();
// @login_required([c1, c2, [c3-1, c3-2]])
// => is_secure: true, credentials: array('c1', 'c2', array('c3', 'c4'))
if (preg_match('/@login_required(?:\(([^\)]*)\))?/', $comment, $matches)) {
$config['is_secure'] = true;
if (!empty($matches[1])) {
$config['credentials'] = self::parseCredentialsText(trim($matches[1], '[]'));
}
} elseif (preg_match('/@login_unrequired/')) {
$config['is_secure'] = false;
}
return $config;
}
static public function parseCredentialsText($text, $main = true)
{
static $cursor;
if ($main) {
$cursor = 0;
}
$credentials = array();
while ($cursor < strlen($text)) {
if (preg_match('/[\s,]+/A', $text, $match, null, $cursor)) {
$cursor += strlen($match[0]);
} elseif (preg_match('/[\w-]+/A', $text, $match, null, $cursor)) {
$credentials[] = $match[0];
$cursor += strlen($match[0]);
} elseif (preg_match('/\[/A', $text, $match, null, $cursor)) {
$cursor += strlen($match[0]);
$credentials[] = self::parseCredentialsText($text, false);
} elseif (true !== $main && preg_match('/\]/A', $text, $match, null, $cursor)) {
$cursor += strlen($match[0]);
return $credentials;
} else {
throw new InvalidArgumentException(sprintf('Unable to parse credentials "%s" near "...%s..."', $text, substr($text, $cursor, 10)));
}
}
return $credentials;
}
}
@riaf
Copy link

riaf commented Oct 1, 2010

Awesome!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment