initial commit

This commit is contained in:
Chris Sewell
2012-11-28 03:55:08 -05:00
parent 7adb399b2e
commit cf140a2e97
3247 changed files with 492437 additions and 0 deletions

1014
lib/symfony/util/Spyc.class.php Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,522 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfBrowser simulates a fake browser which can surf a symfony application.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfBrowser.class.php 4750 2007-07-31 08:46:44Z fabien $
*/
class sfBrowser
{
protected
$context = null,
$hostname = null,
$remote = null,
$dom = null,
$stack = array(),
$stackPosition = -1,
$cookieJar = array(),
$fields = array(),
$vars = array(),
$defaultServerArray = array(),
$currentException = null;
public function initialize($hostname = null, $remote = null, $options = array())
{
unset($_SERVER['argv']);
unset($_SERVER['argc']);
// setup our fake environment
$this->hostname = $hostname;
$this->remote = $remote;
sfConfig::set('sf_path_info_array', 'SERVER');
sfConfig::set('sf_test', true);
// we set a session id (fake cookie / persistence)
$this->newSession();
// store default global $_SERVER array
$this->defaultServerArray = $_SERVER;
// register our shutdown function
register_shutdown_function(array($this, 'shutdown'));
}
public function setVar($name, $value)
{
$this->vars[$name] = $value;
return $this;
}
public function setAuth($login, $password)
{
$this->vars['PHP_AUTH_USER'] = $login;
$this->vars['PHP_AUTH_PW'] = $password;
return $this;
}
public function get($uri, $parameters = array())
{
return $this->call($uri, 'get', $parameters);
}
public function post($uri, $parameters = array())
{
return $this->call($uri, 'post', $parameters);
}
public function call($uri, $method = 'get', $parameters = array(), $changeStack = true)
{
$uri = $this->fixUri($uri);
// add uri to the stack
if ($changeStack)
{
$this->stack = array_slice($this->stack, 0, $this->stackPosition + 1);
$this->stack[] = array(
'uri' => $uri,
'method' => $method,
'parameters' => $parameters,
);
$this->stackPosition = count($this->stack) - 1;
}
list($path, $query_string) = false !== ($pos = strpos($uri, '?')) ? array(substr($uri, 0, $pos), substr($uri, $pos + 1)) : array($uri, '');
$query_string = html_entity_decode($query_string);
// remove anchor
$path = preg_replace('/#.*/', '', $path);
// removes all fields from previous request
$this->fields = array();
// prepare the request object
$_SERVER = $this->defaultServerArray;
$_SERVER['HTTP_HOST'] = $this->hostname ? $this->hostname : sfConfig::get('sf_app').'-'.sfConfig::get('sf_environment');
$_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST'];
$_SERVER['SERVER_PORT'] = 80;
$_SERVER['HTTP_USER_AGENT'] = 'PHP5/CLI';
$_SERVER['REMOTE_ADDR'] = $this->remote ? $this->remote : '127.0.0.1';
$_SERVER['REQUEST_METHOD'] = strtoupper($method);
$_SERVER['PATH_INFO'] = $path;
$_SERVER['REQUEST_URI'] = '/index.php'.$uri;
$_SERVER['SCRIPT_NAME'] = '/index.php';
$_SERVER['SCRIPT_FILENAME'] = '/index.php';
$_SERVER['QUERY_STRING'] = $query_string;
foreach ($this->vars as $key => $value)
{
$_SERVER[strtoupper($key)] = $value;
}
// request parameters
$_GET = $_POST = array();
if (strtoupper($method) == 'POST')
{
$_POST = $parameters;
}
if (strtoupper($method) == 'GET')
{
$_GET = $parameters;
}
parse_str($query_string, $qs);
if (is_array($qs))
{
$_GET = array_merge($qs, $_GET);
}
// restore cookies
$_COOKIE = array();
foreach ($this->cookieJar as $name => $cookie)
{
$_COOKIE[$name] = $cookie['value'];
}
// recycle our context object
sfContext::removeInstance();
$this->context = sfContext::getInstance();
// launch request via controller
$controller = $this->context->getController();
$request = $this->context->getRequest();
$response = $this->context->getResponse();
// we register a fake rendering filter
sfConfig::set('sf_rendering_filter', array('sfFakeRenderingFilter', null));
$this->currentException = null;
// dispatch our request
ob_start();
try
{
$controller->dispatch();
}
catch (sfException $e)
{
$this->currentException = $e;
$e->printStackTrace();
}
catch (Exception $e)
{
$this->currentException = $e;
$sfException = new sfException();
$sfException->printStackTrace($e);
}
$retval = ob_get_clean();
if ($this->currentException instanceof sfStopException)
{
$this->currentException = null;
}
// append retval to the response content
$response->setContent($retval);
// manually shutdown user to save current session data
$this->context->getUser()->shutdown();
$this->context->getStorage()->shutdown();
// save cookies
$this->cookieJar = array();
foreach ($response->getCookies() as $name => $cookie)
{
// FIXME: deal with expire, path, secure, ...
$this->cookieJar[$name] = $cookie;
}
// for HTML/XML content, create a DOM and sfDomCssSelector objects for the response content
if (preg_match('/(x|ht)ml/i', $response->getContentType()))
{
$this->dom = new DomDocument('1.0', sfConfig::get('sf_charset'));
$this->dom->validateOnParse = true;
@$this->dom->loadHTML($response->getContent());
$this->domCssSelector = new sfDomCssSelector($this->dom);
}
else
{
$this->dom = null;
$this->domCssSelector = null;
}
return $this;
}
public function back()
{
if ($this->stackPosition < 1)
{
throw new sfException('You are already on the first page.');
}
--$this->stackPosition;
return $this->call($this->stack[$this->stackPosition]['uri'], $this->stack[$this->stackPosition]['method'], $this->stack[$this->stackPosition]['parameters'], false);
}
public function forward()
{
if ($this->stackPosition > count($this->stack) - 2)
{
throw new sfException('You are already on the last page.');
}
++$this->stackPosition;
return $this->call($this->stack[$this->stackPosition]['uri'], $this->stack[$this->stackPosition]['method'], $this->stack[$this->stackPosition]['parameters'], false);
}
public function reload()
{
if (-1 == $this->stackPosition)
{
throw new sfException('No page to reload.');
}
return $this->call($this->stack[$this->stackPosition]['uri'], $this->stack[$this->stackPosition]['method'], $this->stack[$this->stackPosition]['parameters'], false);
}
public function getResponseDomCssSelector()
{
if (is_null($this->dom))
{
throw new sfException('The DOM is not accessible because the browser response content type is not HTML.');
}
return $this->domCssSelector;
}
public function getResponseDom()
{
if (is_null($this->dom))
{
throw new sfException('The DOM is not accessible because the browser response content type is not HTML.');
}
return $this->dom;
}
public function getContext()
{
return $this->context;
}
public function getResponse()
{
return $this->context->getResponse();
}
public function getRequest()
{
return $this->context->getRequest();
}
public function getCurrentException()
{
return $this->currentException;
}
public function followRedirect()
{
if (null === $this->getContext()->getResponse()->getHttpHeader('Location'))
{
throw new sfException('The request was not redirected');
}
return $this->get($this->getContext()->getResponse()->getHttpHeader('Location'));
}
public function setField($name, $value)
{
// as we don't know yet the form, just store name/value pairs
$this->parseArgumentAsArray($name, $value, $this->fields);
return $this;
}
// link or button
public function click($name, $arguments = array())
{
$dom = $this->getResponseDom();
if (!$dom)
{
throw new sfException('Cannot click because there is no current page in the browser');
}
$xpath = new DomXpath($dom);
// text link
if ($link = $xpath->query(sprintf('//a[.="%s"]', $name))->item(0))
{
return $this->get($link->getAttribute('href'));
}
// image link
if ($link = $xpath->query(sprintf('//a/img[@alt="%s"]/ancestor::a', $name))->item(0))
{
return $this->get($link->getAttribute('href'));
}
// form
if (!$form = $xpath->query(sprintf('//input[((@type="submit" or @type="button") and @value="%s") or (@type="image" and @alt="%s")]/ancestor::form', $name, $name))->item(0))
{
throw new sfException(sprintf('Cannot find the "%s" link or button.', $name));
}
// form attributes
$url = $form->getAttribute('action');
$method = $form->getAttribute('method') ? strtolower($form->getAttribute('method')) : 'get';
// merge form default values and arguments
$defaults = array();
foreach ($xpath->query('descendant::input | descendant::textarea | descendant::select', $form) as $element)
{
$elementName = $element->getAttribute('name');
$nodeName = $element->nodeName;
$value = null;
if ($nodeName == 'input' && ($element->getAttribute('type') == 'checkbox' || $element->getAttribute('type') == 'radio'))
{
if ($element->getAttribute('checked'))
{
$value = $element->getAttribute('value');
}
}
else if (
$nodeName == 'input'
&&
(($element->getAttribute('type') != 'submit' && $element->getAttribute('type') != 'button') || $element->getAttribute('value') == $name)
&&
($element->getAttribute('type') != 'image' || $element->getAttribute('alt') == $name)
)
{
$value = $element->getAttribute('value');
}
else if ($nodeName == 'textarea')
{
$value = '';
foreach ($element->childNodes as $el)
{
$value .= $dom->saveXML($el);
}
}
else if ($nodeName == 'select')
{
if ($multiple = $element->hasAttribute('multiple'))
{
$elementName = str_replace('[]', '', $elementName);
$value = array();
}
else
{
$value = null;
}
$found = false;
foreach ($xpath->query('descendant::option', $element) as $option)
{
if ($option->getAttribute('selected'))
{
$found = true;
if ($multiple)
{
$value[] = $option->getAttribute('value');
}
else
{
$value = $option->getAttribute('value');
}
}
}
// if no option is selected and if it is a simple select box, take the first option as the value
if (!$found && !$multiple)
{
$value = $xpath->query('descendant::option', $element)->item(0)->getAttribute('value');
}
}
if (null !== $value)
{
$this->parseArgumentAsArray($elementName, $value, $defaults);
}
}
// create request parameters
$arguments = sfToolkit::arrayDeepMerge($defaults, $this->fields, $arguments);
if ('post' == $method)
{
return $this->post($url, $arguments);
}
else
{
$query_string = http_build_query($arguments);
$sep = false === strpos($url, '?') ? '?' : '&';
return $this->get($url.($query_string ? $sep.$query_string : ''));
}
}
protected function parseArgumentAsArray($name, $value, &$vars)
{
if (false !== $pos = strpos($name, '['))
{
$var = &$vars;
$tmps = array_filter(preg_split('/(\[ | \[\] | \])/x', $name));
foreach ($tmps as $tmp)
{
$var = &$var[$tmp];
}
if ($var)
{
if (!is_array($var))
{
$var = array($var);
}
$var[] = $value;
}
else
{
$var = $value;
}
}
else
{
$vars[$name] = $value;
}
}
public function restart()
{
$this->newSession();
$this->cookieJar = array();
$this->stack = array();
$this->fields = array();
$this->vars = array();
$this->dom = null;
$this->stackPosition = -1;
return $this;
}
public function shutdown()
{
// we remove all session data
sfToolkit::clearDirectory(sfConfig::get('sf_test_cache_dir').'/sessions');
}
protected function fixUri($uri)
{
// remove absolute information if needed (to be able to do follow redirects, click on links, ...)
if (0 === strpos($uri, 'http'))
{
// detect secure request
if (0 === strpos($uri, 'https'))
{
$this->defaultServerArray['HTTPS'] = 'on';
}
else
{
unset($this->defaultServerArray['HTTPS']);
}
$uri = substr($uri, strpos($uri, 'index.php') + strlen('index.php'));
}
$uri = str_replace('/index.php', '', $uri);
// # as a uri
if ($uri && '#' == $uri[0])
{
$uri = $this->stack[$this->stackPosition]['uri'].$uri;
}
return $uri;
}
protected function newSession()
{
$_SERVER['session_id'] = md5(uniqid(rand(), true));
}
}
class sfFakeRenderingFilter extends sfFilter
{
public function execute($filterChain)
{
$filterChain->execute();
$this->getContext()->getResponse()->sendContent();
}
}

View File

@ -0,0 +1,331 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) 2004-2006 Sean Kerr.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfContext provides information about the current application context, such as
* the module and action names and the module directory. References to the
* current controller, request, and user implementation instances are also
* provided.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Sean Kerr <skerr@mojavi.org>
* @version SVN: $Id: sfContext.class.php 3493 2007-02-18 09:23:10Z fabien $
*/
class sfContext
{
protected
$actionStack = null,
$controller = null,
$databaseManager = null,
$request = null,
$response = null,
$storage = null,
$viewCacheManager = null,
$i18n = null,
$logger = null,
$user = null;
protected static
$instance = null;
/**
* Removes current sfContext instance
*
* This method only exists for testing purpose. Don't use it in your application code.
*/
public static function removeInstance()
{
self::$instance = null;
}
protected function initialize()
{
$this->logger = sfLogger::getInstance();
if (sfConfig::get('sf_logging_enabled'))
{
$this->logger->info('{sfContext} initialization');
}
if (sfConfig::get('sf_use_database'))
{
// setup our database connections
$this->databaseManager = new sfDatabaseManager();
$this->databaseManager->initialize();
}
// create a new action stack
$this->actionStack = new sfActionStack();
// include the factories configuration
require(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_config_dir_name').'/factories.yml'));
// register our shutdown function
register_shutdown_function(array($this, 'shutdown'));
}
/**
* Retrieve the singleton instance of this class.
*
* @return sfContext A sfContext implementation instance.
*/
public static function getInstance()
{
if (!isset(self::$instance))
{
$class = __CLASS__;
self::$instance = new $class();
self::$instance->initialize();
}
return self::$instance;
}
public static function hasInstance()
{
return isset(self::$instance);
}
/**
* Retrieve the action name for this context.
*
* @return string The currently executing action name, if one is set,
* otherwise null.
*/
public function getActionName()
{
// get the last action stack entry
if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
{
return $lastEntry->getActionName();
}
}
/**
* Retrieve the ActionStack.
*
* @return sfActionStack the sfActionStack instance
*/
public function getActionStack()
{
return $this->actionStack;
}
/**
* Retrieve the controller.
*
* @return sfController The current sfController implementation instance.
*/
public function getController()
{
return $this->controller;
}
public function getLogger()
{
return $this->logger;
}
/**
* Retrieve a database connection from the database manager.
*
* This is a shortcut to manually getting a connection from an existing
* database implementation instance.
*
* If the [sf_use_database] setting is off, this will return null.
*
* @param name A database name.
*
* @return mixed A Database instance.
*
* @throws <b>sfDatabaseException</b> If the requested database name does not exist.
*/
public function getDatabaseConnection($name = 'default')
{
if ($this->databaseManager != null)
{
return $this->databaseManager->getDatabase($name)->getConnection();
}
return null;
}
public function retrieveObjects($class, $peerMethod)
{
$retrievingClass = 'sf'.ucfirst(sfConfig::get('sf_orm', 'propel')).'DataRetriever';
return call_user_func(array($retrievingClass, 'retrieveObjects'), $class, $peerMethod);
}
/**
* Retrieve the database manager.
*
* @return sfDatabaseManager The current sfDatabaseManager instance.
*/
public function getDatabaseManager()
{
return $this->databaseManager;
}
/**
* Retrieve the module directory for this context.
*
* @return string An absolute filesystem path to the directory of the
* currently executing module, if one is set, otherwise null.
*/
public function getModuleDirectory()
{
// get the last action stack entry
if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
{
return sfConfig::get('sf_app_module_dir').'/'.$lastEntry->getModuleName();
}
}
/**
* Retrieve the module name for this context.
*
* @return string The currently executing module name, if one is set,
* otherwise null.
*/
public function getModuleName()
{
// get the last action stack entry
if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
{
return $lastEntry->getModuleName();
}
}
/**
* Retrieve the curretn view instance for this context.
*
* @return sfView The currently view instance, if one is set,
* otherwise null.
*/
public function getCurrentViewInstance()
{
// get the last action stack entry
if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
{
return $lastEntry->getViewInstance();
}
}
/**
* Retrieve the request.
*
* @return sfRequest The current sfRequest implementation instance.
*/
public function getRequest()
{
return $this->request;
}
/**
* Retrieve the response.
*
* @return sfResponse The current sfResponse implementation instance.
*/
public function getResponse()
{
return $this->response;
}
/**
* Set the response object.
*
* @param sfResponse A sfResponse instance.
*
* @return void.
*/
public function setResponse($response)
{
$this->response = $response;
}
/**
* Retrieve the storage.
*
* @return sfStorage The current sfStorage implementation instance.
*/
public function getStorage()
{
return $this->storage;
}
/**
* Retrieve the view cache manager
*
* @return sfViewCacheManager The current sfViewCacheManager implementation instance.
*/
public function getViewCacheManager()
{
return $this->viewCacheManager;
}
/**
* Retrieve the i18n instance
*
* @return sfI18N The current sfI18N implementation instance.
*/
public function getI18N()
{
if (!$this->i18n && sfConfig::get('sf_i18n'))
{
$this->i18n = sfI18N::getInstance();
$this->i18n->initialize($this);
}
return $this->i18n;
}
/**
* Retrieve the user.
*
* @return sfUser The current sfUser implementation instance.
*/
public function getUser()
{
return $this->user;
}
/**
* Execute the shutdown procedure.
*
* @return void
*/
public function shutdown()
{
// shutdown all factories
$this->getUser()->shutdown();
$this->getStorage()->shutdown();
$this->getRequest()->shutdown();
$this->getResponse()->shutdown();
if (sfConfig::get('sf_logging_enabled'))
{
$this->getLogger()->shutdown();
}
if (sfConfig::get('sf_use_database'))
{
$this->getDatabaseManager()->shutdown();
}
if (sfConfig::get('sf_cache'))
{
$this->getViewCacheManager()->shutdown();
}
}
}

273
lib/symfony/util/sfCore.class.php Executable file
View File

@ -0,0 +1,273 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* core symfony class.
*
* @package symfony
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfCore.class.php 4203 2007-06-10 09:24:03Z fabien $
*/
class sfCore
{
static protected
$autoloadCallables = array(),
$classes = array();
static public function bootstrap($sf_symfony_lib_dir, $sf_symfony_data_dir)
{
require_once($sf_symfony_lib_dir.'/util/sfToolkit.class.php');
require_once($sf_symfony_lib_dir.'/config/sfConfig.class.php');
sfCore::initConfiguration($sf_symfony_lib_dir, $sf_symfony_data_dir);
sfCore::initIncludePath();
sfCore::callBootstrap();
if (sfConfig::get('sf_check_lock'))
{
sfCore::checkLock();
}
if (sfConfig::get('sf_check_symfony_version'))
{
sfCore::checkSymfonyVersion();
}
}
static public function callBootstrap()
{
$bootstrap = sfConfig::get('sf_config_cache_dir').'/config_bootstrap_compile.yml.php';
if (is_readable($bootstrap))
{
sfConfig::set('sf_in_bootstrap', true);
require($bootstrap);
}
else
{
require(sfConfig::get('sf_symfony_lib_dir').'/symfony.php');
}
}
static public function initConfiguration($sf_symfony_lib_dir, $sf_symfony_data_dir, $test = false)
{
// start timer
if (SF_DEBUG)
{
sfConfig::set('sf_timer_start', microtime(true));
}
// main configuration
sfConfig::add(array(
'sf_root_dir' => SF_ROOT_DIR,
'sf_app' => SF_APP,
'sf_environment' => SF_ENVIRONMENT,
'sf_debug' => SF_DEBUG,
'sf_symfony_lib_dir' => $sf_symfony_lib_dir,
'sf_symfony_data_dir' => $sf_symfony_data_dir,
'sf_test' => $test,
));
// directory layout
include($sf_symfony_data_dir.'/config/constants.php');
}
static public function initIncludePath()
{
set_include_path(
sfConfig::get('sf_lib_dir').PATH_SEPARATOR.
sfConfig::get('sf_root_dir').PATH_SEPARATOR.
sfConfig::get('sf_app_lib_dir').PATH_SEPARATOR.
sfConfig::get('sf_symfony_lib_dir').DIRECTORY_SEPARATOR.'vendor'.PATH_SEPARATOR.
get_include_path()
);
}
// check to see if we're not in a cache cleaning process
static public function checkLock()
{
if (sfToolkit::hasLockFile(SF_ROOT_DIR.DIRECTORY_SEPARATOR.SF_APP.'_'.SF_ENVIRONMENT.'.lck', 5))
{
// application is not available
$file = sfConfig::get('sf_web_dir').'/errors/unavailable.php';
include(is_readable($file) ? $file : sfConfig::get('sf_symfony_data_dir').'/web/errors/unavailable.php');
die(1);
}
}
static public function checkSymfonyVersion()
{
// recent symfony update?
$last_version = @file_get_contents(sfConfig::get('sf_config_cache_dir').'/VERSION');
$current_version = trim(file_get_contents(sfConfig::get('sf_symfony_lib_dir').'/VERSION'));
if ($last_version != $current_version)
{
// clear cache
sfToolkit::clearDirectory(sfConfig::get('sf_config_cache_dir'));
}
}
static public function getClassPath($class)
{
return isset(self::$classes[$class]) ? self::$classes[$class] : null;
}
static public function addAutoloadCallable($callable)
{
self::$autoloadCallables[] = $callable;
if (function_exists('spl_autoload_register'))
{
spl_autoload_register($callable);
}
}
static public function getAutoloadCallables()
{
return self::$autoloadCallables;
}
/**
* Handles autoloading of classes that have been specified in autoload.yml.
*
* @param string A class name.
*
* @return boolean Returns true if the class has been loaded
*/
static public function splAutoload($class)
{
// load the list of autoload classes
if (!self::$classes)
{
$file = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_config_dir_name').'/autoload.yml');
self::$classes = include($file);
}
// class already exists
if (class_exists($class, false))
{
return true;
}
// we have a class path, let's include it
if (isset(self::$classes[$class]))
{
require(self::$classes[$class]);
return true;
}
// see if the file exists in the current module lib directory
// must be in a module context
if (sfContext::hasInstance() && ($module = sfContext::getInstance()->getModuleName()) && isset(self::$classes[$module.'/'.$class]))
{
require(self::$classes[$module.'/'.$class]);
return true;
}
return false;
}
static public function initAutoload()
{
if (function_exists('spl_autoload_register'))
{
ini_set('unserialize_callback_func', 'spl_autoload_call');
}
else if (!function_exists('__autoload'))
{
ini_set('unserialize_callback_func', '__autoload');
function __autoload($class)
{
foreach (sfCore::getAutoloadCallables() as $callable)
{
if (call_user_func($callable, $class))
{
return true;
}
}
// unspecified class
// do not print an error if the autoload came from class_exists
$trace = debug_backtrace();
if (count($trace) < 1 || ($trace[1]['function'] != 'class_exists' && $trace[1]['function'] != 'is_a'))
{
$error = sprintf('Autoloading of class "%s" failed. Try to clear the symfony cache and refresh. [err0003]', $class);
$e = new sfAutoloadException($error);
$e->printStackTrace();
}
}
}
self::addAutoloadCallable(array('sfCore', 'splAutoload'));
}
static public function splSimpleAutoload($class)
{
// class already exists
if (class_exists($class, false))
{
return true;
}
// we have a class path, let's include it
if (isset(self::$classes[$class]))
{
require(self::$classes[$class]);
return true;
}
return false;
}
static public function initSimpleAutoload($dirs)
{
require_once(dirname(__FILE__).'/sfFinder.class.php');
self::$classes = array();
$finder = sfFinder::type('file')->ignore_version_control()->name('*.php');
foreach ((array) $dirs as $dir)
{
$files = $finder->in(glob($dir));
if (is_array($files))
{
foreach ($files as $file)
{
preg_match_all('~^\s*(?:abstract\s+|final\s+)?(?:class|interface)\s+(\w+)~mi', file_get_contents($file), $classes);
foreach ($classes[1] as $class)
{
self::$classes[$class] = $file;
}
}
}
}
if (function_exists('spl_autoload_register'))
{
ini_set('unserialize_callback_func', 'spl_autoload_call');
spl_autoload_register(array('sfCore', 'splSimpleAutoload'));
}
elseif (!function_exists('__autoload'))
{
ini_set('unserialize_callback_func', '__autoload');
function __autoload($class)
{
return sfCore::splSimpleAutoload($class);
}
}
}
}

View File

@ -0,0 +1,303 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfDomCssSelector allows to navigate a DOM with CSS selector.
*
* based on getElementsBySelector version 0.4 - Simon Willison, March 25th 2003
* http://simon.incutio.com/archive/2003/03/25/getElementsBySelector
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfDomCssSelector.class.php 4236 2007-06-18 08:40:13Z fabien $
*/
class sfDomCssSelector
{
protected $dom = null;
public function __construct($dom)
{
$this->dom = $dom;
}
public function getTexts($selector)
{
$texts = array();
foreach ($this->getElements($selector) as $element)
{
$texts[] = $element->nodeValue;
}
return $texts;
}
public function getElements($selector)
{
$all_nodes = array();
foreach ($this->tokenize_selectors($selector) as $selector)
{
$nodes = array($this->dom);
foreach ($this->tokenize($selector) as $token)
{
$combinator = $token['combinator'];
$token = trim($token['name']);
$pos = strpos($token, '#');
if (false !== $pos && preg_match('/^[A-Za-z0-9]*$/', substr($token, 0, $pos)))
{
// Token is an ID selector
$tagName = substr($token, 0, $pos);
$id = substr($token, $pos + 1);
$xpath = new DomXPath($this->dom);
$element = $xpath->query(sprintf("//*[@id = '%s']", $id))->item(0);
if (!$element || ($tagName && strtolower($element->nodeName) != $tagName))
{
// tag with that ID not found
return array();
}
// Set nodes to contain just this element
$nodes = array($element);
continue; // Skip to next token
}
$pos = strpos($token, '.');
if (false !== $pos && preg_match('/^[A-Za-z0-9]*$/', substr($token, 0, $pos)))
{
// Token contains a class selector
$tagName = substr($token, 0, $pos);
if (!$tagName)
{
$tagName = '*';
}
$className = substr($token, $pos + 1);
// Get elements matching tag, filter them for class selector
$founds = $this->getElementsByTagName($nodes, $tagName, $combinator);
$nodes = array();
foreach ($founds as $found)
{
if (preg_match('/\b'.$className.'\b/', $found->getAttribute('class')))
{
$nodes[] = $found;
}
}
continue; // Skip to next token
}
// Code to deal with attribute selectors
if (preg_match('/^(\w*)(\[.+\])$/', $token, $matches))
{
$tagName = $matches[1] ? $matches[1] : '*';
preg_match_all('/
\[
(\w+) # attribute
([=~\|\^\$\*]?) # modifier (optional)
=? # equal (optional)
(
"([^"]*)" # quoted value (optional)
|
([^\]]*) # non quoted value (optional)
)
\]
/x', $matches[2], $matches, PREG_SET_ORDER);
// Grab all of the tagName elements within current node
$founds = $this->getElementsByTagName($nodes, $tagName, $combinator);
$nodes = array();
foreach ($founds as $found)
{
$ok = false;
foreach ($matches as $match)
{
$attrName = $match[1];
$attrOperator = $match[2];
$attrValue = $match[4];
switch ($attrOperator)
{
case '=': // Equality
$ok = $found->getAttribute($attrName) == $attrValue;
break;
case '~': // Match one of space seperated words
$ok = preg_match('/\b'.preg_quote($attrValue, '/').'\b/', $found->getAttribute($attrName));
break;
case '|': // Match start with value followed by optional hyphen
$ok = preg_match('/^'.preg_quote($attrValue, '/').'-?/', $found->getAttribute($attrName));
break;
case '^': // Match starts with value
$ok = 0 === strpos($found->getAttribute($attrName), $attrValue);
break;
case '$': // Match ends with value
$ok = $attrValue == substr($found->getAttribute($attrName), -strlen($attrValue));
break;
case '*': // Match ends with value
$ok = false !== strpos($found->getAttribute($attrName), $attrValue);
break;
default :
// Just test for existence of attribute
$ok = $found->hasAttribute($attrName);
}
if (false == $ok)
{
break;
}
}
if ($ok)
{
$nodes[] = $found;
}
}
continue; // Skip to next token
}
// If we get here, token is JUST an element (not a class or ID selector)
$nodes = $this->getElementsByTagName($nodes, $token, $combinator);
}
foreach ($nodes as $node)
{
if (!$node->getAttribute('sf_matched'))
{
$node->setAttribute('sf_matched', true);
$all_nodes[] = $node;
}
}
}
foreach ($all_nodes as $node)
{
$node->removeAttribute('sf_matched');
}
return $all_nodes;
}
protected function getElementsByTagName($nodes, $tagName, $combinator = ' ')
{
$founds = array();
foreach ($nodes as $node)
{
switch ($combinator)
{
case ' ':
// Descendant selector
foreach ($node->getElementsByTagName($tagName) as $element)
{
$founds[] = $element;
}
break;
case '>':
// Child selector
foreach ($node->childNodes as $element)
{
if ($tagName == $element->nodeName)
{
$founds[] = $element;
}
}
break;
case '+':
// Adjacent selector
$element = $node->nextSibling;
if ($element && '#text' == $element->nodeName)
{
$element = $element->nextSibling;
}
if ($element && $tagName == $element->nodeName)
{
$founds[] = $element;
}
break;
}
}
return $founds;
}
protected function tokenize_selectors($selector)
{
// split tokens by , except in an attribute selector
$tokens = array();
$quoted = false;
$token = '';
for ($i = 0, $max = strlen($selector); $i < $max; $i++)
{
if (',' == $selector[$i] && !$quoted)
{
$tokens[] = trim($token);
$token = '';
}
else if ('"' == $selector[$i])
{
$token .= $selector[$i];
$quoted = $quoted ? false : true;
}
else
{
$token .= $selector[$i];
}
}
if ($token)
{
$tokens[] = trim($token);
}
return $tokens;
}
protected function tokenize($selector)
{
// split tokens by space except if space is in an attribute selector
$tokens = array();
$combinators = array(' ', '>', '+');
$quoted = false;
$token = array('combinator' => ' ', 'name' => '');
for ($i = 0, $max = strlen($selector); $i < $max; $i++)
{
if (in_array($selector[$i], $combinators) && !$quoted)
{
// remove all whitespaces around the combinator
$combinator = $selector[$i];
while (in_array($selector[$i + 1], $combinators))
{
if (' ' != $selector[++$i])
{
$combinator = $selector[$i];
}
}
$tokens[] = $token;
$token = array('combinator' => $combinator, 'name' => '');
}
else if ('"' == $selector[$i])
{
$token['name'] .= $selector[$i];
$quoted = $quoted ? false : true;
}
else
{
$token['name'] .= $selector[$i];
}
}
if ($token['name'])
{
$tokens[] = $token;
}
return $tokens;
}
}

View File

@ -0,0 +1,216 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfFillInForm.class.php 4883 2007-08-20 14:15:13Z fabien $
*/
class sfFillInForm
{
protected
$converters = array(),
$skipFields = array(),
$types = array('text', 'checkbox', 'radio', 'hidden', 'password');
public function addConverter($callable, $fields)
{
foreach ((array) $fields as $field)
{
$this->converters[$field][] = $callable;
}
}
public function setSkipFields($fields)
{
$this->skipFields = $fields;
}
public function setTypes($types)
{
$this->types = $types;
}
public function fillInHtml($html, $formName, $formId, $values)
{
$dom = new DomDocument('1.0', sfConfig::get('sf_charset', 'UTF-8'));
@$dom->loadHTML($html);
$dom = $this->fillInDom($dom, $formName, $formId, $values);
return $dom->saveHTML();
}
public function fillInXml($xml, $formName, $formId, $values)
{
$dom = new DomDocument('1.0', sfConfig::get('sf_charset', 'UTF-8'));
@$dom->loadXML($xml);
$dom = $this->fillInDom($dom, $formName, $formId, $values);
return $dom->saveXML();
}
public function fillInDom($dom, $formName, $formId, $values)
{
$xpath = new DomXPath($dom);
if ($dom->documentElement && $dom->documentElement->namespaceURI)
{
$xpath->registerNamespace('xhtml', $dom->documentElement->namespaceURI);
$ns = 'xhtml:';
}
else
{
$ns = '';
}
$query = 'descendant::'.$ns.'input[@name and (not(@type)';
foreach ($this->types as $type)
{
$query .= ' or @type="'.$type.'"';
}
$query .= ')] | descendant::'.$ns.'textarea[@name] | descendant::'.$ns.'select[@name]';
// find our form
if ($formName)
{
$xpath_query = '//'.$ns.'form[@name="'.$formName.'"]';
}
elseif ($formId)
{
$xpath_query = '//'.$ns.'form[@id="'.$formId.'"]';
}
else
{
$xpath_query = '//'.$ns.'form';
}
$form = $xpath->query($xpath_query)->item(0);
if (!$form)
{
if (!$formName && !$formId)
{
throw new sfException('No form found in this page');
}
else
{
throw new sfException(sprintf('The form "%s" cannot be found', $formName ? $formName : $formId));
}
}
foreach ($xpath->query($query, $form) as $element)
{
$name = (string) $element->getAttribute('name');
$value = (string) $element->getAttribute('value');
$type = (string) $element->getAttribute('type');
// skip fields
if (!$this->hasValue($values, $name) || in_array($name, $this->skipFields))
{
continue;
}
if ($element->nodeName == 'input')
{
if ($type == 'checkbox' || $type == 'radio')
{
// checkbox and radio
$element->removeAttribute('checked');
if ($this->hasValue($values, $name) && ($this->getValue($values, $name) == $value || !$element->hasAttribute('value')))
{
$element->setAttribute('checked', 'checked');
}
}
else
{
// text input
$element->removeAttribute('value');
if ($this->hasValue($values, $name))
{
$element->setAttribute('value', $this->escapeValue($this->getValue($values, $name), $name));
}
}
}
else if ($element->nodeName == 'textarea')
{
$el = $element->cloneNode(false);
$el->appendChild($dom->createTextNode($this->escapeValue($this->getValue($values, $name), $name)));
$element->parentNode->replaceChild($el, $element);
}
else if ($element->nodeName == 'select')
{
// select
$value = $this->getValue($values, $name);
$multiple = $element->hasAttribute('multiple');
foreach ($xpath->query('descendant::'.$ns.'option', $element) as $option)
{
$option->removeAttribute('selected');
if ($multiple && is_array($value))
{
if (in_array($option->getAttribute('value'), $value))
{
$option->setAttribute('selected', 'selected');
}
}
else if ($value == $option->getAttribute('value'))
{
$option->setAttribute('selected', 'selected');
}
}
}
}
return $dom;
}
protected function hasValue($values, $name)
{
if (array_key_exists($name, $values))
{
return true;
}
return null !== sfToolkit::getArrayValueForPath($values, $name);
}
protected function getValue($values, $name)
{
if (array_key_exists($name, $values))
{
return $values[$name];
}
return sfToolkit::getArrayValueForPath($values, $name);
}
protected function escapeValue($value, $name)
{
if (function_exists('iconv') && strtolower(sfConfig::get('sf_charset')) != 'utf-8')
{
$new_value = iconv(sfConfig::get('sf_charset'), 'UTF-8', $value);
if (false !== $new_value)
{
$value = $new_value;
}
}
if (isset($this->converters[$name]))
{
foreach ($this->converters[$name] as $callable)
{
$value = call_user_func($callable, $value);
}
}
return $value;
}
}

View File

@ -0,0 +1,723 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
*/
/**
*
* Allow to build rules to find files and directories.
*
* All rules may be invoked several times, except for ->in() method.
* Some rules are cumulative (->name() for example) whereas others are destructive
* (most recent value is used, ->maxdepth() method for example).
*
* All methods return the current sfFinder object to allow easy chaining:
*
* $files = sfFinder::type('file')->name('*.php')->in(.);
*
* Interface loosely based on perl File::Find::Rule module.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
*/
class sfFinder
{
protected $type = 'file';
protected $names = array();
protected $prunes = array();
protected $discards = array();
protected $execs = array();
protected $mindepth = 0;
protected $sizes = array();
protected $maxdepth = 1000000;
protected $relative = false;
protected $follow_link = false;
/**
* Sets maximum directory depth.
*
* Finder will descend at most $level levels of directories below the starting point.
*
* @param integer level
* @return object current sfFinder object
*/
public function maxdepth($level)
{
$this->maxdepth = $level;
return $this;
}
/**
* Sets minimum directory depth.
*
* Finder will start applying tests at level $level.
*
* @param integer level
* @return object current sfFinder object
*/
public function mindepth($level)
{
$this->mindepth = $level;
return $this;
}
public function get_type()
{
return $this->type;
}
/**
* Sets the type of elements to returns.
*
* @param string directory or file or any (for both file and directory)
* @return object new sfFinder object
*/
public static function type($name)
{
$finder = new sfFinder();
if (strtolower(substr($name, 0, 3)) == 'dir')
{
$finder->type = 'directory';
}
else if (strtolower($name) == 'any')
{
$finder->type = 'any';
}
else
{
$finder->type = 'file';
}
return $finder;
}
/*
* glob, patterns (must be //) or strings
*/
protected function to_regex($str)
{
if ($str{0} == '/' && $str{strlen($str) - 1} == '/')
{
return $str;
}
else
{
return sfGlobToRegex::glob_to_regex($str);
}
}
protected function args_to_array($arg_list, $not = false)
{
$list = array();
for ($i = 0; $i < count($arg_list); $i++)
{
if (is_array($arg_list[$i]))
{
foreach ($arg_list[$i] as $arg)
{
$list[] = array($not, $this->to_regex($arg));
}
}
else
{
$list[] = array($not, $this->to_regex($arg_list[$i]));
}
}
return $list;
}
/**
* Adds rules that files must match.
*
* You can use patterns (delimited with / sign), globs or simple strings.
*
* $finder->name('*.php')
* $finder->name('/\.php$/') // same as above
* $finder->name('test.php')
*
* @param list a list of patterns, globs or strings
* @return object current sfFinder object
*/
public function name()
{
$args = func_get_args();
$this->names = array_merge($this->names, $this->args_to_array($args));
return $this;
}
/**
* Adds rules that files must not match.
*
* @see ->name()
* @param list a list of patterns, globs or strings
* @return object current sfFinder object
*/
public function not_name()
{
$args = func_get_args();
$this->names = array_merge($this->names, $this->args_to_array($args, true));
return $this;
}
/**
* Adds tests for file sizes.
*
* $finder->size('> 10K');
* $finder->size('<= 1Ki');
* $finder->size(4);
*
* @param list a list of comparison strings
* @return object current sfFinder object
*/
public function size()
{
$args = func_get_args();
for ($i = 0; $i < count($args); $i++)
{
$this->sizes[] = new sfNumberCompare($args[$i]);
}
return $this;
}
/**
* Traverses no further.
*
* @param list a list of patterns, globs to match
* @return object current sfFinder object
*/
public function prune()
{
$args = func_get_args();
$this->prunes = array_merge($this->prunes, $this->args_to_array($args));
return $this;
}
/**
* Discards elements that matches.
*
* @param list a list of patterns, globs to match
* @return object current sfFinder object
*/
public function discard()
{
$args = func_get_args();
$this->discards = array_merge($this->discards, $this->args_to_array($args));
return $this;
}
/**
* Ignores version control directories.
*
* Currently supports subversion, CVS, DARCS, Gnu Arch, Monotone, Bazaar-NG
*
* @return object current pakeFinder object
*/
public function ignore_version_control()
{
$ignores = array('.svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr');
return $this->discard($ignores)->prune($ignores);
}
/**
* Executes function or method for each element.
*
* Element match if functino or method returns true.
*
* $finder->exec('myfunction');
* $finder->exec(array($object, 'mymethod'));
*
* @param mixed function or method to call
* @return object current sfFinder object
*/
public function exec()
{
$args = func_get_args();
for ($i = 0; $i < count($args); $i++)
{
if (is_array($args[$i]) && !method_exists($args[$i][0], $args[$i][1]))
{
throw new sfException("method {$args[$i][1]} does not exist for object {$args[$i][0]}");
}
else if (!is_array($args[$i]) && !function_exists($args[$i]))
{
throw new sfException("function {$args[$i]} does not exist");
}
$this->execs[] = $args[$i];
}
return $this;
}
/**
* Returns relative paths for all files and directories.
*
* @return object current sfFinder object
*/
public function relative()
{
$this->relative = true;
return $this;
}
/**
* Symlink following.
*
* @return object current sfFinder object
*/
public function follow_link()
{
$this->follow_link = true;
return $this;
}
/**
* Searches files and directories which match defined rules.
*
* @return array list of files and directories
*/
public function in()
{
$files = array();
$here_dir = getcwd();
$numargs = func_num_args();
$arg_list = func_get_args();
// first argument is an array?
if ($numargs == 1 && is_array($arg_list[0]))
{
$arg_list = $arg_list[0];
$numargs = count($arg_list);
}
for ($i = 0; $i < $numargs; $i++)
{
$real_dir = realpath($arg_list[$i]);
// absolute path?
if (!self::isPathAbsolute($real_dir))
{
$dir = $here_dir.DIRECTORY_SEPARATOR.$real_dir;
}
else
{
$dir = $real_dir;
}
if (!is_dir($real_dir))
{
continue;
}
if ($this->relative)
{
$files = array_merge($files, str_replace($dir.DIRECTORY_SEPARATOR, '', $this->search_in($dir)));
}
else
{
$files = array_merge($files, $this->search_in($dir));
}
}
return array_unique($files);
}
protected function search_in($dir, $depth = 0)
{
if ($depth > $this->maxdepth)
{
return array();
}
if (is_link($dir) && !$this->follow_link)
{
return array();
}
$files = array();
if (is_dir($dir))
{
$current_dir = opendir($dir);
while (false !== $entryname = readdir($current_dir))
{
if ($entryname == '.' || $entryname == '..') continue;
$current_entry = $dir.DIRECTORY_SEPARATOR.$entryname;
if (is_link($current_entry) && !$this->follow_link)
{
continue;
}
if (is_dir($current_entry))
{
if (($this->type == 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->exec_ok($dir, $entryname))
{
$files[] = realpath($current_entry);
}
if (!$this->is_pruned($dir, $entryname))
{
$files = array_merge($files, $this->search_in($current_entry, $depth + 1));
}
}
else
{
if (($this->type != 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->size_ok($dir, $entryname) && $this->exec_ok($dir, $entryname))
{
$files[] = realpath($current_entry);
}
}
}
closedir($current_dir);
}
return $files;
}
protected function match_names($dir, $entry)
{
if (!count($this->names)) return true;
// we must match one "not_name" rules to be ko
$one_not_name_rule = false;
foreach ($this->names as $args)
{
list($not, $regex) = $args;
if ($not)
{
$one_not_name_rule = true;
if (preg_match($regex, $entry))
{
return false;
}
}
}
$one_name_rule = false;
// we must match one "name" rules to be ok
foreach ($this->names as $args)
{
list($not, $regex) = $args;
if (!$not)
{
$one_name_rule = true;
if (preg_match($regex, $entry))
{
return true;
}
}
}
if ($one_not_name_rule && $one_name_rule)
{
return false;
}
else if ($one_not_name_rule)
{
return true;
}
else if ($one_name_rule)
{
return false;
}
else
{
return true;
}
}
protected function size_ok($dir, $entry)
{
if (!count($this->sizes)) return true;
if (!is_file($dir.DIRECTORY_SEPARATOR.$entry)) return true;
$filesize = filesize($dir.DIRECTORY_SEPARATOR.$entry);
foreach ($this->sizes as $number_compare)
{
if (!$number_compare->test($filesize)) return false;
}
return true;
}
protected function is_pruned($dir, $entry)
{
if (!count($this->prunes)) return false;
foreach ($this->prunes as $args)
{
$regex = $args[1];
if (preg_match($regex, $entry)) return true;
}
return false;
}
protected function is_discarded($dir, $entry)
{
if (!count($this->discards)) return false;
foreach ($this->discards as $args)
{
$regex = $args[1];
if (preg_match($regex, $entry)) return true;
}
return false;
}
protected function exec_ok($dir, $entry)
{
if (!count($this->execs)) return true;
foreach ($this->execs as $exec)
{
if (!call_user_func_array($exec, array($dir, $entry))) return false;
}
return true;
}
public static function isPathAbsolute($path)
{
if ($path{0} == '/' || $path{0} == '\\' ||
(strlen($path) > 3 && ctype_alpha($path{0}) &&
$path{1} == ':' &&
($path{2} == '\\' || $path{2} == '/')
)
)
{
return true;
}
return false;
}
}
/**
* Match globbing patterns against text.
*
* if match_glob("foo.*", "foo.bar") echo "matched\n";
*
* // prints foo.bar and foo.baz
* $regex = glob_to_regex("foo.*");
* for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t)
* {
* if (/$regex/) echo "matched: $car\n";
* }
*
* sfGlobToRegex implements glob(3) style matching that can be used to match
* against text, rather than fetching names from a filesystem.
*
* based on perl Text::Glob module.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@gmail.com> php port
* @author Richard Clamp <richardc@unixbeard.net> perl version
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@gmail.com>
* @copyright 2002 Richard Clamp <richardc@unixbeard.net>
* @version SVN: $Id: sfFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
*/
class sfGlobToRegex
{
protected static $strict_leading_dot = true;
protected static $strict_wildcard_slash = true;
public static function setStrictLeadingDot($boolean)
{
self::$strict_leading_dot = $boolean;
}
public static function setStrictWildcardSlash($boolean)
{
self::$strict_wildcard_slash = $boolean;
}
/**
* Returns a compiled regex which is the equiavlent of the globbing pattern.
*
* @param string glob pattern
* @return string regex
*/
public static function glob_to_regex($glob)
{
$first_byte = true;
$escaping = false;
$in_curlies = 0;
$regex = '';
for ($i = 0; $i < strlen($glob); $i++)
{
$car = $glob[$i];
if ($first_byte)
{
if (self::$strict_leading_dot && $car != '.')
{
$regex .= '(?=[^\.])';
}
$first_byte = false;
}
if ($car == '/')
{
$first_byte = true;
}
if ($car == '.' || $car == '(' || $car == ')' || $car == '|' || $car == '+' || $car == '^' || $car == '$')
{
$regex .= "\\$car";
}
else if ($car == '*')
{
$regex .= ($escaping ? "\\*" : (self::$strict_wildcard_slash ? "[^/]*" : ".*"));
}
else if ($car == '?')
{
$regex .= ($escaping ? "\\?" : (self::$strict_wildcard_slash ? "[^/]" : "."));
}
else if ($car == '{')
{
$regex .= ($escaping ? "\\{" : "(");
if (!$escaping) ++$in_curlies;
}
else if ($car == '}' && $in_curlies)
{
$regex .= ($escaping ? "}" : ")");
if (!$escaping) --$in_curlies;
}
else if ($car == ',' && $in_curlies)
{
$regex .= ($escaping ? "," : "|");
}
else if ($car == "\\")
{
if ($escaping)
{
$regex .= "\\\\";
$escaping = false;
}
else
{
$escaping = true;
}
continue;
}
else
{
$regex .= $car;
$escaping = false;
}
$escaping = false;
}
return "#^$regex$#";
}
}
/**
* Numeric comparisons.
*
* sfNumberCompare compiles a simple comparison to an anonymous
* subroutine, which you can call with a value to be tested again.
* Now this would be very pointless, if sfNumberCompare didn't understand
* magnitudes.
* The target value may use magnitudes of kilobytes (k, ki),
* megabytes (m, mi), or gigabytes (g, gi). Those suffixed
* with an i use the appropriate 2**n version in accordance with the
* IEC standard: http://physics.nist.gov/cuu/Units/binary.html
*
* based on perl Number::Compare module.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@gmail.com> php port
* @author Richard Clamp <richardc@unixbeard.net> perl version
* @copyright 2004-2005 Fabien Potencier <fabien.potencier@gmail.com>
* @copyright 2002 Richard Clamp <richardc@unixbeard.net>
* @see http://physics.nist.gov/cuu/Units/binary.html
* @version SVN: $Id: sfFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
*/
class sfNumberCompare
{
protected $test = '';
public function __construct($test)
{
$this->test = $test;
}
public function test($number)
{
if (!preg_match('{^([<>]=?)?(.*?)([kmg]i?)?$}i', $this->test, $matches))
{
throw new sfException('don\'t understand "'.$this->test.'" as a test');
}
$target = array_key_exists(2, $matches) ? $matches[2] : '';
$magnitude = array_key_exists(3, $matches) ? $matches[3] : '';
if (strtolower($magnitude) == 'k') $target *= 1000;
if (strtolower($magnitude) == 'ki') $target *= 1024;
if (strtolower($magnitude) == 'm') $target *= 1000000;
if (strtolower($magnitude) == 'mi') $target *= 1024*1024;
if (strtolower($magnitude) == 'g') $target *= 1000000000;
if (strtolower($magnitude) == 'gi') $target *= 1024*1024*1024;
$comparison = array_key_exists(1, $matches) ? $matches[1] : '==';
if ($comparison == '==' || $comparison == '')
{
return ($number == $target);
}
else if ($comparison == '>')
{
return ($number > $target);
}
else if ($comparison == '>=')
{
return ($number >= $target);
}
else if ($comparison == '<')
{
return ($number < $target);
}
else if ($comparison == '<=')
{
return ($number <= $target);
}
return false;
}
}

View File

@ -0,0 +1,118 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfInflector.class.php 1415 2006-06-11 08:33:51Z fabien $
*/
class sfInflector
{
/**
* Returns a camelized string from a lower case and underscored string by replaceing slash with
* double-colol and upper-casing each letter preceded by an underscore.
*
* @param string String to camelize.
*
* @return string Camelized string.
*/
public static function camelize($lower_case_and_underscored_word)
{
$tmp = $lower_case_and_underscored_word;
$tmp = sfToolkit::pregtr($tmp, array('#/(.?)#e' => "'::'.strtoupper('\\1')",
'/(^|_)(.)/e' => "strtoupper('\\2')"));
return $tmp;
}
/**
* Returns an underscore-syntaxed version or the CamelCased string.
*
* @param string String to underscore.
*
* @return string Underscored string.
*/
public static function underscore($camel_cased_word)
{
$tmp = $camel_cased_word;
$tmp = str_replace('::', '/', $tmp);
$tmp = sfToolkit::pregtr($tmp, array('/([A-Z]+)([A-Z][a-z])/' => '\\1_\\2',
'/([a-z\d])([A-Z])/' => '\\1_\\2'));
return strtolower($tmp);
}
/**
* Returns classname::module with classname:: stripped off.
*
* @param string Classname and module pair.
*
* @return string Module name.
*/
public static function demodulize($class_name_in_module)
{
return preg_replace('/^.*::/', '', $class_name_in_module);
}
/**
* Returns classname in underscored form, with "_id" tacked on at the end.
* This is for use in dealing with foreign keys in the database.
*
* @param string Class name.
* @param boolean Seperate with underscore.
*
* @return strong Foreign key
*/
public static function foreign_key($class_name, $separate_class_name_and_id_with_underscore = true)
{
return sfInflector::underscore(sfInflector::demodulize($class_name)).($separate_class_name_and_id_with_underscore ? "_id" : "id");
}
/**
* Returns corresponding table name for given classname.
*
* @param string Name of class to get database table name for.
*
* @return string Name of the databse table for given class.
*/
public static function tableize($class_name)
{
return sfInflector::underscore($class_name);
}
/**
* Returns model class name for given database table.
*
* @param string Table name.
*
* @return string Classified table name.
*/
public static function classify($table_name)
{
return sfInflector::camelize($table_name);
}
/**
* Returns a human-readable string from a lower case and underscored word by replacing underscores
* with a space, and by upper-casing the initial characters.
*
* @param string String to make more readable.
*
* @return string Human-readable string.
*/
public static function humanize($lower_case_and_underscored_word)
{
if (substr($lower_case_and_underscored_word, -3) === '_id')
$lower_case_and_underscored_word = substr($lower_case_and_underscored_word, 0, -3);
return ucfirst(str_replace('_', ' ', $lower_case_and_underscored_word));
}
}

View File

@ -0,0 +1,194 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfMixer implements mixins and hooks.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfMixer.class.php 2845 2006-11-28 16:41:45Z fabien $
*/
class sfMixer
{
static protected
$mixins = array(),
$mixinParameters = array(),
$mixinInstances = array();
static public function register($name, $callable)
{
$lazy = false;
if (is_array($callable))
{
$mixinClass = $callable[0];
$mixinMethod = $callable[1];
if (!is_object($mixinClass))
{
$rc = new ReflectionClass($mixinClass);
$rm = $rc->getMethod($mixinMethod);
if (!$rm->isStatic())
{
$lazy = true;
}
}
}
else
{
$mixinMethod = $callable;
}
$tmp = explode(':', $name);
$class = $tmp[0];
// do we have a method name
if (isset($tmp[1]))
{
$method = $tmp[1];
// do we have a hook name
if (isset($tmp[2]))
{
$hook = $tmp[2];
}
else
{
$hook = $method;
$name .= ':'.$hook;
}
}
else
{
// this will be called with __call
$method = $mixinMethod;
$name = $class.':'.$method;
$hook = '';
}
// we cannot register 2 new methods with the same name
if (!$hook && isset(self::$mixins[$name]))
{
throw new Exception(sprintf('The class "%s" has already a mixin for method "%s"', $class, $mixinMethod));
}
// register mixin
if (!isset(self::$mixins[$name]))
{
self::$mixins[$name] = array();
}
if (!isset(self::$mixinParameters[$name]))
{
self::$mixinParameters[$name] = array();
}
self::$mixins[$name][] = $callable;
self::$mixinParameters[$name][] = array(
'lazy' => $lazy,
'class' => $class,
'method' => $method,
'hook' => $hook,
);
}
static public function getMixinInstance($name)
{
if (!isset(self::$mixins[$name]))
{
return;
}
foreach (self::$mixins[$name] as $i => $mixin)
{
if (!self::$mixinParameters[$name][$i]['lazy'])
{
continue;
}
$class = $mixin[0];
if (!isset(self::$mixinInstances[$class]))
{
self::$mixinInstances[$class] = new $class();
if (method_exists(self::$mixinInstances[$class], 'initialize'))
{
self::$mixinInstances[$class]->initialize();
}
}
self::$mixinParameters[$name][$i]['lazy'] = false;
self::$mixins[$name][$i][0] = self::$mixinInstances[$class];
}
}
static public function getCallables($name)
{
self::getMixinInstance($name);
return isset(self::$mixins[$name]) ? self::$mixins[$name] : array();
}
static public function getCallable($name)
{
self::getMixinInstance($name);
return isset(self::$mixins[$name]) ? self::$mixins[$name][0] : null;
}
static public function callMixins($hookName = null, $moreParams = array())
{
$traces = debug_backtrace();
$function = $traces[1]['function'];
$parameters = $traces[1]['args'];
$class = $traces[1]['class'];
$type = $traces[1]['type'];
if ('__call' == $function)
{
$method = $parameters[0];
$parameters = $parameters[1];
}
else
{
$method = $function;
}
if ('->' == $type)
{
array_unshift($parameters, $traces[1]['object']);
}
else
{
array_unshift($parameters, $class);
}
// add more parameters
$parameters = array_merge($parameters, (array) $moreParams);
if ('__call' == $function)
{
if ($callable = self::getCallable($class.':'.$method))
{
return call_user_func_array($callable, $parameters);
}
else
{
throw new Exception(sprintf('Call to undefined method %s::%s', $class, $method));
}
}
else
{
$hookName = $hookName ? $hookName : $method;
foreach (self::getCallables($class.':'.$method.':'.$hookName) as $callable)
{
call_user_func_array($callable, $parameters);
}
}
}
}

View File

@ -0,0 +1,386 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) 2004-2006 Sean Kerr.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfParameterHolder provides a base class for managing parameters.
*
* Parameters, in this case, are used to extend classes with additional data
* that requires no additional logic to manage.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Sean Kerr <skerr@mojavi.org>
* @version SVN: $Id: sfParameterHolder.class.php 3329 2007-01-23 08:29:34Z fabien $
*/
class sfParameterHolder
{
protected $default_namespace = null;
protected $parameters = array();
/**
* The constructor for sfParameterHolder.
*
* The default namespace may be overridden at initialization as follows:
* <code>
* <?php
* $mySpecialPH = new sfParameterHolder('symfony/special');
* ?>
* </code>
*/
public function __construct($namespace = 'symfony/default')
{
$this->default_namespace = $namespace;
}
/**
* Get the default namespace value.
*
* The $default_namespace is defined as 'symfony/default'.
*
* @return string The default namespace.
*/
public function getDefaultNamespace()
{
return $this->default_namespace;
}
/**
* Clear all parameters associated with this request.
*
* @return void
*/
public function clear()
{
$this->parameters = null;
$this->parameters = array();
}
/**
* Retrieve a parameter with an optionally specified namespace.
*
* An isolated namespace may be identified by providing a value for the third
* argument. If not specified, the default namespace 'symfony/default' is
* used.
*
* @param string A parameter name.
* @param mixed A default parameter value.
* @param string A parameter namespace.
*
* @return mixed A parameter value, if the parameter exists, otherwise null.
*/
public function & get($name, $default = null, $ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
if (isset($this->parameters[$ns][$name]))
{
$value = & $this->parameters[$ns][$name];
}
else if (isset($this->parameters[$ns]))
{
$value = sfToolkit::getArrayValueForPath($this->parameters[$ns], $name, $default);
}
else
{
$value = $default;
}
return $value;
}
/**
* Retrieve an array of parameter names from an optionally specified namespace.
*
* @param string A parameter namespace.
*
* @return array An indexed array of parameter names, if the namespace exists, otherwise null.
*/
public function getNames($ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
if (isset($this->parameters[$ns]))
{
return array_keys($this->parameters[$ns]);
}
return array();
}
/**
* Retrieve an array of parameter namespaces.
*
* @return array An indexed array of parameter namespaces.
*/
public function getNamespaces()
{
return array_keys($this->parameters);
}
/**
* Retrieve an array of parameters, within a namespace.
*
* This method is limited to a namespace. Without any argument,
* it returns the parameters of the default namespace. If a
* namespace is passed as an argument, only the parameters of the
* specified namespace are returned.
*
* @param string A parameter namespace.
*
* @return array An associative array of parameters.
*/
public function & getAll($ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
$parameters = array();
if (isset($this->parameters[$ns]))
{
$parameters = $this->parameters[$ns];
}
return $parameters;
}
/**
* Indicates whether or not a parameter exists.
*
* @param string A parameter name.
* @param string A parameter namespace.
*
* @return bool true, if the parameter exists, otherwise false.
*/
public function has($name, $ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
if (false !== ($offset = strpos($name, '[')))
{
if (isset($this->parameters[$ns][substr($name, 0, $offset)]))
{
$array = $this->parameters[$ns][substr($name, 0, $offset)];
while ($pos = strpos($name, '[', $offset))
{
$end = strpos($name, ']', $pos);
if ($end == $pos + 1)
{
// reached a []
return true;
}
else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
{
return false;
}
$array = $array[substr($name, $pos + 1, $end - $pos - 1)];
$offset = $end;
}
return true;
}
}
elseif (isset($this->parameters[$ns][$name]))
{
return true;
}
return false;
}
/**
* Indicates whether or not A parameter namespace exists.
*
* @param string A parameter namespace.
*
* @return bool true, if the namespace exists, otherwise false.
*/
public function hasNamespace($ns)
{
return isset($this->parameters[$ns]);
}
/**
* Remove a parameter.
*
* @param string A parameter name.
* @param string A parameter namespace.
*
* @return string A parameter value, if the parameter was removed, otherwise null.
*/
public function & remove($name, $ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
$retval = null;
if (isset($this->parameters[$ns]) && isset($this->parameters[$ns][$name]))
{
$retval =& $this->parameters[$ns][$name];
unset($this->parameters[$ns][$name]);
}
return $retval;
}
/**
* Remove A parameter namespace and all of its associated parameters.
*
* @param string A parameter namespace.
*
* @return void
*/
public function & removeNamespace($ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
$retval = null;
if (isset($this->parameters[$ns]))
{
$retval =& $this->parameters[$ns];
unset($this->parameters[$ns]);
}
return $retval;
}
/**
* Set a parameter.
*
* If a parameter with the name already exists the value will be overridden.
*
* @param string A parameter name.
* @param mixed A parameter value.
* @param string A parameter namespace.
*
* @return void
*/
public function set($name, $value, $ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
if (!isset($this->parameters[$ns]))
{
$this->parameters[$ns] = array();
}
$this->parameters[$ns][$name] = $value;
}
/**
* Set a parameter by reference.
*
* If a parameter with the name already exists the value will be overridden.
*
* @param string A parameter name.
* @param mixed A reference to a parameter value.
* @param string A parameter namespace.
*
* @return void
*/
public function setByRef($name, & $value, $ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
if (!isset($this->parameters[$ns]))
{
$this->parameters[$ns] = array();
}
$this->parameters[$ns][$name] =& $value;
}
/**
* Set an array of parameters.
*
* If an existing parameter name matches any of the keys in the supplied
* array, the associated value will be overridden.
*
* @param array An associative array of parameters and their associated values.
* @param string A parameter namespace.
*
* @return void
*/
public function add($parameters, $ns = null)
{
if ($parameters === null) return;
if (!$ns)
{
$ns = $this->default_namespace;
}
if (!isset($this->parameters[$ns]))
{
$this->parameters[$ns] = array();
}
foreach ($parameters as $key => $value)
{
$this->parameters[$ns][$key] = $value;
}
}
/**
* Set an array of parameters by reference.
*
* If an existing parameter name matches any of the keys in the supplied
* array, the associated value will be overridden.
*
* @param array An associative array of parameters and references to their associated values.
* @param string A parameter namespace.
*
* @return void
*/
public function addByRef(& $parameters, $ns = null)
{
if (!$ns)
{
$ns = $this->default_namespace;
}
if (!isset($this->parameters[$ns]))
{
$this->parameters[$ns] = array();
}
foreach ($parameters as $key => &$value)
{
$this->parameters[$ns][$key] =& $value;
}
}
}

View File

@ -0,0 +1,551 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) 2004-2006 Sean Kerr.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfToolkit provides basic utility methods.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @author Sean Kerr <skerr@mojavi.org>
* @version SVN: $Id: sfToolkit.class.php 4385 2007-06-25 16:40:04Z fabien $
*/
class sfToolkit
{
/**
* Extract the class or interface name from filename.
*
* @param string A filename.
*
* @return string A class or interface name, if one can be extracted, otherwise null.
*/
public static function extractClassName($filename)
{
$retval = null;
if (self::isPathAbsolute($filename))
{
$filename = basename($filename);
}
$pattern = '/(.*?)\.(class|interface)\.php/i';
if (preg_match($pattern, $filename, $match))
{
$retval = $match[1];
}
return $retval;
}
/**
* Clear all files in a given directory.
*
* @param string An absolute filesystem path to a directory.
*
* @return void
*/
public static function clearDirectory($directory)
{
if (!is_dir($directory))
{
return;
}
// open a file point to the cache dir
$fp = opendir($directory);
// ignore names
$ignore = array('.', '..', 'CVS', '.svn');
while (($file = readdir($fp)) !== false)
{
if (!in_array($file, $ignore))
{
if (is_link($directory.'/'.$file))
{
// delete symlink
unlink($directory.'/'.$file);
}
else if (is_dir($directory.'/'.$file))
{
// recurse through directory
self::clearDirectory($directory.'/'.$file);
// delete the directory
rmdir($directory.'/'.$file);
}
else
{
// delete the file
unlink($directory.'/'.$file);
}
}
}
// close file pointer
fclose($fp);
}
/**
* Clear all files and directories corresponding to a glob pattern.
*
* @param string An absolute filesystem pattern.
*
* @return void
*/
public static function clearGlob($pattern)
{
$files = glob($pattern);
// order is important when removing directories
sort($files);
foreach ($files as $file)
{
if (is_dir($file))
{
// delete directory
self::clearDirectory($file);
}
else
{
// delete file
unlink($file);
}
}
}
/**
* Determine if a filesystem path is absolute.
*
* @param path A filesystem path.
*
* @return bool true, if the path is absolute, otherwise false.
*/
public static function isPathAbsolute($path)
{
if ($path[0] == '/' || $path[0] == '\\' ||
(strlen($path) > 3 && ctype_alpha($path[0]) &&
$path[1] == ':' &&
($path[2] == '\\' || $path[2] == '/')
)
)
{
return true;
}
return false;
}
/**
* Determine if a lock file is present.
*
* @param integer A max amount of life time for the lock file.
*
* @return bool true, if the lock file is present, otherwise false.
*/
public static function hasLockFile($lockFile, $maxLockFileLifeTime = 0)
{
$isLocked = false;
if (is_readable($lockFile) && ($last_access = fileatime($lockFile)))
{
$now = time();
$timeDiff = $now - $last_access;
if (!$maxLockFileLifeTime || $timeDiff < $maxLockFileLifeTime)
{
$isLocked = true;
}
else
{
$isLocked = @unlink($lockFile) ? false : true;
}
}
return $isLocked;
}
public static function stripComments($source)
{
if (!sfConfig::get('sf_strip_comments', true))
{
return $source;
}
// tokenizer available?
if (!function_exists('token_get_all'))
{
$source = sfToolkit::pregtr($source, array('#/\*((?!\*/)[\d\D\s])*\*/#' => '', // remove /* ... */
'#^\s*//.*$#m' => '')); // remove // ...
return $source;
}
$output = '';
$tokens = token_get_all($source);
foreach ($tokens as $token)
{
if (is_string($token))
{
// simple 1-character token
$output .= $token;
}
else
{
// token array
list($id, $text) = $token;
switch ($id)
{
case T_COMMENT:
case T_DOC_COMMENT:
// no action on comments
break;
default:
// anything else -> output "as is"
$output .= $text;
break;
}
}
}
return $output;
}
public static function stripslashesDeep($value)
{
return is_array($value) ? array_map(array('sfToolkit', 'stripslashesDeep'), $value) : stripslashes($value);
}
// code from php at moechofe dot com (array_merge comment on php.net)
/*
* array arrayDeepMerge ( array array1 [, array array2 [, array ...]] )
*
* Like array_merge
*
* arrayDeepMerge() merges the elements of one or more arrays together so
* that the values of one are appended to the end of the previous one. It
* returns the resulting array.
* If the input arrays have the same string keys, then the later value for
* that key will overwrite the previous one. If, however, the arrays contain
* numeric keys, the later value will not overwrite the original value, but
* will be appended.
* If only one array is given and the array is numerically indexed, the keys
* get reindexed in a continuous way.
*
* Different from array_merge
* If string keys have arrays for values, these arrays will merge recursively.
*/
public static function arrayDeepMerge()
{
switch (func_num_args())
{
case 0:
return false;
case 1:
return func_get_arg(0);
case 2:
$args = func_get_args();
$args[2] = array();
if (is_array($args[0]) && is_array($args[1]))
{
foreach (array_unique(array_merge(array_keys($args[0]),array_keys($args[1]))) as $key)
{
$isKey0 = array_key_exists($key, $args[0]);
$isKey1 = array_key_exists($key, $args[1]);
if ($isKey0 && $isKey1 && is_array($args[0][$key]) && is_array($args[1][$key]))
{
$args[2][$key] = self::arrayDeepMerge($args[0][$key], $args[1][$key]);
}
else if ($isKey0 && $isKey1)
{
$args[2][$key] = $args[1][$key];
}
else if (!$isKey1)
{
$args[2][$key] = $args[0][$key];
}
else if (!$isKey0)
{
$args[2][$key] = $args[1][$key];
}
}
return $args[2];
}
else
{
return $args[1];
}
default :
$args = func_get_args();
$args[1] = sfToolkit::arrayDeepMerge($args[0], $args[1]);
array_shift($args);
return call_user_func_array(array('sfToolkit', 'arrayDeepMerge'), $args);
break;
}
}
public static function stringToArray($string)
{
preg_match_all('/
\s*(\w+) # key \\1
\s*=\s* # =
(\'|")? # values may be included in \' or " \\2
(.*?) # value \\3
(?(2) \\2) # matching \' or " if needed \\4
\s*(?:
(?=\w+\s*=) | \s*$ # followed by another key= or the end of the string
)
/x', $string, $matches, PREG_SET_ORDER);
$attributes = array();
foreach ($matches as $val)
{
$attributes[$val[1]] = self::literalize($val[3]);
}
return $attributes;
}
/**
* Finds the type of the passed value, returns the value as the new type.
*
* @param string
* @return mixed
*/
public static function literalize($value, $quoted = false)
{
// lowercase our value for comparison
$value = trim($value);
$lvalue = strtolower($value);
if (in_array($lvalue, array('null', '~', '')))
{
$value = null;
}
else if (in_array($lvalue, array('true', 'on', '+', 'yes')))
{
$value = true;
}
else if (in_array($lvalue, array('false', 'off', '-', 'no')))
{
$value = false;
}
else if (ctype_digit($value))
{
$value = (int) $value;
}
else if (is_numeric($value))
{
$value = (float) $value;
}
else
{
$value = self::replaceConstants($value);
if ($quoted)
{
$value = '\''.str_replace('\'', '\\\'', $value).'\'';
}
}
return $value;
}
/**
* Replaces constant identifiers in a scalar value.
*
* @param string the value to perform the replacement on
* @return string the value with substitutions made
*/
public static function replaceConstants($value)
{
return is_string($value) ? preg_replace('/%(.+?)%/e', 'sfConfig::has(strtolower("\\1")) ? sfConfig::get(strtolower("\\1")) : "%\\1%"', $value) : $value;
}
/**
* Returns subject replaced with regular expression matchs
*
* @param mixed subject to search
* @param array array of search => replace pairs
*/
public static function pregtr($search, $replacePairs)
{
return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
}
public static function isArrayValuesEmpty($array)
{
static $isEmpty = true;
foreach ($array as $value)
{
$isEmpty = (is_array($value)) ? self::isArrayValuesEmpty($value) : (strlen($value) == 0);
if (!$isEmpty)
{
break;
}
}
return $isEmpty;
}
/**
* Checks if a string is an utf8.
*
* Yi Stone Li<yili@yahoo-inc.com>
* Copyright (c) 2007 Yahoo! Inc. All rights reserved.
* Licensed under the BSD open source license
*
* @param string
*
* @return bool true if $string is valid UTF-8 and false otherwise.
*/
public static function isUTF8($string)
{
for ($idx = 0, $strlen = strlen($string); $idx < $strlen; $idx++)
{
$byte = ord($string[$idx]);
if ($byte & 0x80)
{
if (($byte & 0xE0) == 0xC0)
{
// 2 byte char
$bytes_remaining = 1;
}
else if (($byte & 0xF0) == 0xE0)
{
// 3 byte char
$bytes_remaining = 2;
}
else if (($byte & 0xF8) == 0xF0)
{
// 4 byte char
$bytes_remaining = 3;
}
else
{
return false;
}
if ($idx + $bytes_remaining >= $strlen)
{
return false;
}
while ($bytes_remaining--)
{
if ((ord($string[++$idx]) & 0xC0) != 0x80)
{
return false;
}
}
}
}
return true;
}
public static function getArrayValueForPath($values, $name, $default = null)
{
if (false !== ($offset = strpos($name, '[')))
{
if (isset($values[substr($name, 0, $offset)]))
{
$array = $values[substr($name, 0, $offset)];
while ($pos = strpos($name, '[', $offset))
{
$end = strpos($name, ']', $pos);
if ($end == $pos + 1)
{
// reached a []
break;
}
else if (!isset($array[substr($name, $pos + 1, $end - $pos - 1)]))
{
return $default;
}
$array = $array[substr($name, $pos + 1, $end - $pos - 1)];
$offset = $end;
}
return $array;
}
}
return $default;
}
public static function getPhpCli()
{
$path = getenv('PATH') ? getenv('PATH') : getenv('Path');
$suffixes = DIRECTORY_SEPARATOR == '\\' ? (getenv('PATHEXT') ? explode(PATH_SEPARATOR, getenv('PATHEXT')) : array('.exe', '.bat', '.cmd', '.com')) : array('');
foreach (array('php5', 'php') as $phpCli)
{
foreach ($suffixes as $suffix)
{
foreach (explode(PATH_SEPARATOR, $path) as $dir)
{
$file = $dir.DIRECTORY_SEPARATOR.$phpCli.$suffix;
if (is_executable($file))
{
return $file;
}
}
}
}
throw new sfException('Unable to find PHP executable');
}
/**
* From PEAR System.php
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @author Tomas V.V.Cox <cox@idecnet.com>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
*/
public static function getTmpDir()
{
if (DIRECTORY_SEPARATOR == '\\')
{
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP'))
{
return $var;
}
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP'))
{
return $var;
}
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir'))
{
return $var;
}
return getenv('SystemRoot').'\temp';
}
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR'))
{
return $var;
}
return '/tmp';
}
}

105
lib/symfony/util/sfYaml.class.php Executable file
View File

@ -0,0 +1,105 @@
<?php
/*
* This file is part of the symfony package.
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfYaml class.
*
* @package symfony
* @subpackage util
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
* @version SVN: $Id: sfYaml.class.php 3378 2007-02-01 06:47:15Z fabien $
*/
class sfYaml
{
/**
* Load YAML into a PHP array statically
*
* The load method, when supplied with a YAML stream (string or file),
* will do its best to convert YAML in a file into a PHP array.
*
* Usage:
* <code>
* $array = sfYAML::Load('config.yml');
* print_r($array);
* </code>
*
* @return array
* @param string $input Path of YAML file or string containing YAML
*/
public static function load($input)
{
$input = self::getIncludeContents($input);
// if an array is returned by the config file assume it's in plain php form else in yaml
if (is_array($input))
{
return $input;
}
// syck is prefered over spyc
if (function_exists('syck_load'))
{
$retval = syck_load($input);
return is_array($retval) ? $retval : array();
}
else
{
require_once(dirname(__FILE__).'/Spyc.class.php');
$spyc = new Spyc();
return $spyc->load($input);
}
}
/**
* Dump YAML from PHP array statically
*
* The dump method, when supplied with an array, will do its best
* to convert the array into friendly YAML.
*
* @return string
* @param array $array PHP array
*/
public static function dump($array)
{
require_once(dirname(__FILE__).'/Spyc.class.php');
$spyc = new Spyc();
return $spyc->dump($array);
}
protected static function getIncludeContents($input)
{
// if input is a file, process it
if (strpos($input, "\n") === false && is_file($input))
{
ob_start();
$retval = include($input);
$contents = ob_get_clean();
// if an array is returned by the config file assume it's in plain php form else in yaml
return is_array($retval) ? $retval : $contents;
}
// else return original input
return $input;
}
}
/**
* Wraps echo to automatically provide a newline
*/
function echoln($string)
{
echo $string."\n";
}