Nette-2.1.0/ 40777 0 0 0 12261522617 5614 5 Nette-2.1.0/license.txt 100777 0 0 5337 12261522617 10107 0 Licenses
========
Good news! You may use Nette Framework under the terms of either
the New BSD License or the GNU General Public License (GPL) version 2 or 3.
The BSD License is recommended for most projects. It is easy to understand and it
places almost no restrictions on what you can do with the framework. If the GPL
fits better to your project, you can use the framework under this license.
You don't have to notify anyone which license you are using. You can freely
use Nette Framework in commercial projects as long as the copyright header
remains intact.
Please be advised that the name "Nette Framework" is a protected trademark and its
usage has some limitations. So please do not use word "Nette" in the name of your
project or top-level domain, and choose a name that stands on its own merits.
If your stuff is good, it will not take long to establish a reputation for yourselves.
New BSD License
---------------
Copyright (c) 2004, 2014 David Grudl (http://davidgrudl.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of "Nette Framework" nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall the copyright owner or contributors be liable for
any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused and on
any theory of liability, whether in contract, strict liability, or tort
(including negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.
GNU General Public License
--------------------------
GPL licenses are very very long, so instead of including them here we offer
you URLs with full text:
- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html)
- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html)
Nette-2.1.0/Nette/ 40777 0 0 0 12261522617 6673 5 Nette-2.1.0/Nette/Application/ 40777 0 0 0 12261522616 11135 5 Nette-2.1.0/Nette/Application/Application.php 100777 0 0 13314 12261522616 14233 0 httpRequest = $httpRequest;
$this->httpResponse = $httpResponse;
$this->presenterFactory = $presenterFactory;
$this->router = $router;
}
/**
* Dispatch a HTTP request to a front controller.
* @return void
*/
public function run()
{
try {
$this->onStartup($this);
$this->processRequest($this->createInitialRequest());
$this->onShutdown($this);
} catch (\Exception $e) {
$this->onError($this, $e);
if ($this->catchExceptions && $this->errorPresenter) {
try {
$this->processException($e);
$this->onShutdown($this, $e);
return;
} catch (\Exception $e) {
$this->onError($this, $e);
}
}
$this->onShutdown($this, $e);
throw $e;
}
}
/**
* @return Request
*/
public function createInitialRequest()
{
$request = $this->router->match($this->httpRequest);
if (!$request instanceof Request) {
throw new BadRequestException('No route for HTTP request.');
} elseif (strcasecmp($request->getPresenterName(), $this->errorPresenter) === 0) {
throw new BadRequestException('Invalid request. Presenter is not achievable.');
}
try {
$name = $request->getPresenterName();
$this->presenterFactory->getPresenterClass($name);
$request->setPresenterName($name);
} catch (InvalidPresenterException $e) {
throw new BadRequestException($e->getMessage(), 0, $e);
}
return $request;
}
/**
* @return void
*/
public function processRequest(Request $request)
{
if (count($this->requests) > self::$maxLoop) {
throw new ApplicationException('Too many loops detected in application life cycle.');
}
$this->requests[] = $request;
$this->onRequest($this, $request);
$this->presenter = $this->presenterFactory->createPresenter($request->getPresenterName());
$response = $this->presenter->run($request);
if ($response instanceof Responses\ForwardResponse) {
$this->processRequest($response->getRequest());
} elseif ($response) {
$this->onResponse($this, $response);
$response->send($this->httpRequest, $this->httpResponse);
}
}
/**
* @return void
*/
public function processException(\Exception $e)
{
if (!$this->httpResponse->isSent()) {
$this->httpResponse->setCode($e instanceof BadRequestException ? ($e->getCode() ?: 404) : 500);
}
$args = array('exception' => $e, 'request' => end($this->requests) ?: NULL);
if ($this->presenter instanceof UI\Presenter) {
try {
$this->presenter->forward(":$this->errorPresenter:", $args);
} catch (AbortException $foo) {
$this->processRequest($this->presenter->getLastCreatedRequest());
}
} else {
$this->processRequest(new Request($this->errorPresenter, Request::FORWARD, $args));
}
}
/**
* Returns all processed requests.
* @return Request[]
*/
public function getRequests()
{
return $this->requests;
}
/**
* Returns current presenter.
* @return IPresenter
*/
public function getPresenter()
{
return $this->presenter;
}
/********************* services ****************d*g**/
/**
* Returns router.
* @return IRouter
*/
public function getRouter()
{
return $this->router;
}
/**
* Returns presenter factory.
* @return IPresenterFactory
*/
public function getPresenterFactory()
{
return $this->presenterFactory;
}
/********************* request serialization ****************d*g**/
/** @deprecated */
function storeRequest($expiration = '+ 10 minutes')
{
trigger_error(__METHOD__ . '() is deprecated; use $presenter->storeRequest() instead.', E_USER_DEPRECATED);
return $this->presenter->storeRequest($expiration);
}
/** @deprecated */
function restoreRequest($key)
{
trigger_error(__METHOD__ . '() is deprecated; use $presenter->restoreRequest() instead.', E_USER_DEPRECATED);
return $this->presenter->restoreRequest($key);
}
}
Nette-2.1.0/Nette/Application/Diagnostics/ 40777 0 0 0 12261522616 13404 5 Nette-2.1.0/Nette/Application/Diagnostics/RoutingPanel.php 100777 0 0 7476 12261522616 16642 0 addPanel(function($e) use ($application) {
return $e ? NULL : array(
'tab' => 'Nette Application',
'panel' => '
Requests
' . Dumper::toHtml($application->getRequests())
. 'Presenter
' . Dumper::toHtml($application->getPresenter())
);
});
}
public function __construct(Nette\Application\IRouter $router, Nette\Http\IRequest $httpRequest, Nette\Application\IPresenterFactory $presenterFactory)
{
$this->router = $router;
$this->httpRequest = $httpRequest;
$this->presenterFactory = $presenterFactory;
}
/**
* Renders tab.
* @return string
*/
public function getTab()
{
$this->analyse($this->router);
ob_start();
require __DIR__ . '/templates/RoutingPanel.tab.phtml';
return ob_get_clean();
}
/**
* Renders panel.
* @return string
*/
public function getPanel()
{
ob_start();
require __DIR__ . '/templates/RoutingPanel.panel.phtml';
return ob_get_clean();
}
/**
* Analyses simple route.
* @param Nette\Application\IRouter
* @return void
*/
private function analyse($router, $module = '')
{
if ($router instanceof Routers\RouteList) {
foreach ($router as $subRouter) {
$this->analyse($subRouter, $module . $router->getModule());
}
return;
}
$matched = 'no';
$request = $router->match($this->httpRequest);
if ($request) {
$request->setPresenterName($module . $request->getPresenterName());
$matched = 'may';
if (empty($this->request)) {
$this->request = $request;
$this->findSource();
$matched = 'yes';
}
}
$this->routers[] = array(
'matched' => $matched,
'class' => get_class($router),
'defaults' => $router instanceof Routers\Route || $router instanceof Routers\SimpleRouter ? $router->getDefaults() : array(),
'mask' => $router instanceof Routers\Route ? $router->getMask() : NULL,
'request' => $request,
'module' => rtrim($module, ':')
);
}
private function findSource()
{
$request = $this->request;
$presenter = $request->getPresenterName();
try {
$class = $this->presenterFactory->getPresenterClass($presenter);
} catch (Nette\Application\InvalidPresenterException $e) {
return;
}
$rc = Nette\Reflection\ClassType::from($class);
if ($rc->isSubclassOf('Nette\Application\UI\Presenter')) {
if (isset($request->parameters[Presenter::SIGNAL_KEY])) {
$method = $class::formatSignalMethod($request->parameters[Presenter::SIGNAL_KEY]);
} elseif (isset($request->parameters[Presenter::ACTION_KEY])) {
$action = $request->parameters[Presenter::ACTION_KEY];
$method = $class::formatActionMethod($action);
if (!$rc->hasMethod($method)) {
$method = $class::formatRenderMethod($action);
}
}
}
$this->source = isset($method) && $rc->hasMethod($method) ? $rc->getMethod($method) : $rc;
}
}
Nette-2.1.0/Nette/Application/Diagnostics/templates/ 40777 0 0 0 12261522616 15402 5 Nette-2.1.0/Nette/Application/Diagnostics/templates/RoutingPanel.panel.phtml 100777 0 0 6030 12261522616 22254 0
request)): ?>
no route
request->getPresenterName() . ':' . (isset($this->request->parameters[Presenter::ACTION_KEY]) ? $this->request->parameters[Presenter::ACTION_KEY] : Presenter::DEFAULT_ACTION) . (isset($this->request->parameters[Presenter::SIGNAL_KEY]) ? " {$this->request->parameters[Presenter::SIGNAL_KEY]}!" : '')) ?>
httpRequest->getUrl()) ?>
routers)): ?>
No routers defined.
Matched? |
Class |
Mask |
Defaults |
Module |
Request |
routers as $router): ?>
|
|
|
$value): ?>
TRUE))) ?>
|
|
getParameters(); ?>
getPresenterName() . ':' . (isset($params[Presenter::ACTION_KEY]) ? $params[Presenter::ACTION_KEY] : Presenter::DEFAULT_ACTION)) ?>
$value): ?>
TRUE))) ?>
|
source): ?>
source ?> in source->getFileName(), $this->source->getStartLine()) ?>
Nette-2.1.0/Nette/Application/Diagnostics/templates/RoutingPanel.tab.phtml 100777 0 0 2666 12261522616 21736 0
request)): ?>no routerequest->getPresenterName() . ':' . (isset($this->request->parameters[Presenter::ACTION_KEY]) ? $this->request->parameters[Presenter::ACTION_KEY] : Presenter::DEFAULT_ACTION) . (isset($this->request->parameters[Presenter::SIGNAL_KEY]) ? " {$this->request->parameters[Presenter::SIGNAL_KEY]}!" : '')); endif ?>
Nette-2.1.0/Nette/Application/ErrorPresenter.php 100777 0 0 1476 12261522616 14737 0 parameters['exception'];
if ($e instanceof Application\BadRequestException) {
$code = $e->getCode();
} else {
$code = 500;
Debugger::log($e, Debugger::ERROR);
}
ob_start();
require __DIR__ . '/templates/error.phtml';
return new Application\Responses\TextResponse(ob_get_clean());
}
}
Nette-2.1.0/Nette/Application/exceptions.php 100777 0 0 2261 12261522616 14130 0 504 ? $this->defaultCode : $code, $previous);
}
}
/**
* Forbidden request exception - access denied.
*/
class ForbiddenRequestException extends BadRequestException
{
/** @var int */
protected $defaultCode = 403;
}
Nette-2.1.0/Nette/Application/IPresenter.php 100777 0 0 574 12261522616 14014 0
*/
interface IPresenterFactory
{
/**
* Generates and checks presenter class name.
* @param string presenter name
* @return string class name
* @throws InvalidPresenterException
*/
function getPresenterClass(& $name);
/**
* Creates new presenter instance.
* @param string presenter name
* @return IPresenter
*/
function createPresenter($name);
}
Nette-2.1.0/Nette/Application/IResponse.php 100777 0 0 705 12261522616 13637 0 context = $context;
}
/**
* Gets the context.
* @return \SystemContainer|Nette\DI\Container
*/
public function getContext()
{
return $this->context;
}
/**
* @return Nette\Application\IResponse
*/
public function run(Application\Request $request)
{
$this->request = $request;
$httpRequest = $this->context->getByType('Nette\Http\IRequest');
if (!$httpRequest->isAjax() && ($request->isMethod('get') || $request->isMethod('head'))) {
$refUrl = clone $httpRequest->getUrl();
$url = $this->context->getByType('Nette\Application\IRouter')->constructUrl($request, $refUrl->setPath($refUrl->getScriptPath()));
if ($url !== NULL && !$httpRequest->getUrl()->isEqual($url)) {
return new Responses\RedirectResponse($url, Http\IResponse::S301_MOVED_PERMANENTLY);
}
}
$params = $request->getParameters();
if (!isset($params['callback'])) {
throw new Application\BadRequestException("Parameter callback is missing.");
}
$params['presenter'] = $this;
$callback = $params['callback'];
$reflection = Nette\Utils\Callback::toReflection(Nette\Utils\Callback::check($callback));
$params = Application\UI\PresenterComponentReflection::combineArgs($reflection, $params);
foreach ($reflection->getParameters() as $param) {
if ($param->getClassName()) {
unset($params[$param->getPosition()]);
}
}
$params = Nette\DI\Helpers::autowireArguments($reflection, $params, $this->context);
$response = call_user_func_array($callback, $params);
if (is_string($response)) {
$response = array($response, array());
}
if (is_array($response)) {
if ($response[0] instanceof \SplFileInfo) {
$response = $this->createTemplate('Nette\Templating\FileTemplate')
->setParameters($response[1])->setFile($response[0]);
} else {
$response = $this->createTemplate('Nette\Templating\Template')
->setParameters($response[1])->setSource($response[0]);
}
}
if ($response instanceof Nette\Templating\ITemplate) {
return new Responses\TextResponse($response);
} else {
return $response;
}
}
/**
* Template factory.
* @param string
* @param callable
* @return Nette\Templating\ITemplate
*/
public function createTemplate($class = NULL, $latteFactory = NULL)
{
$template = $class ? new $class : new Nette\Templating\FileTemplate;
$template->setParameters($this->request->getParameters());
$template->presenter = $this;
$template->context = $context = $this->context;
$url = $context->getByType('Nette\Http\IRequest')->getUrl();
$template->baseUrl = rtrim($url->getBaseUrl(), '/');
$template->basePath = rtrim($url->getBasePath(), '/');
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
$template->setCacheStorage($context->getService('nette.templateCacheStorage'));
$template->onPrepareFilters[] = function($template) use ($latteFactory) {
$template->registerFilter($latteFactory ? $latteFactory() : new Nette\Latte\Engine);
};
return $template;
}
/**
* Redirects to another URL.
* @param string
* @param int HTTP code
* @return Nette\Application\Responses\RedirectResponse
*/
public function redirectUrl($url, $code = Http\IResponse::S302_FOUND)
{
return new Responses\RedirectResponse($url, $code);
}
/**
* Throws HTTP error.
* @param string
* @param int HTTP error code
* @return void
* @throws Nette\Application\BadRequestException
*/
public function error($message = NULL, $code = Http\IResponse::S404_NOT_FOUND)
{
throw new Application\BadRequestException($message, $code);
}
/**
* @return Nette\Application\IRequest
*/
public function getRequest()
{
return $this->request;
}
}
Nette-2.1.0/Nette/Application/PresenterFactory.php 100777 0 0 12320 12261522616 15263 0 splited mask */
private $mapping = array(
'*' => array('', '*Module\\', '*Presenter'),
'Nette' => array('NetteModule\\', '*\\', '*Presenter'),
);
/** @var string */
private $baseDir;
/** @var array */
private $cache = array();
/** @var Nette\DI\Container */
private $container;
/**
* @param string
*/
public function __construct($baseDir, Nette\DI\Container $container)
{
$this->baseDir = $baseDir;
$this->container = $container;
}
/**
* Creates new presenter instance.
* @param string presenter name
* @return IPresenter
*/
public function createPresenter($name)
{
$class = $this->getPresenterClass($name);
if (count($services = $this->container->findByType($class)) === 1) {
$presenter = $this->container->createService($services[0]);
} else {
$presenter = $this->container->createInstance($class);
}
$this->container->callInjects($presenter);
if ($presenter instanceof UI\Presenter && $presenter->invalidLinkMode === NULL) {
$presenter->invalidLinkMode = $this->container->parameters['debugMode'] ? UI\Presenter::INVALID_LINK_WARNING : UI\Presenter::INVALID_LINK_SILENT;
}
return $presenter;
}
/**
* Generates and checks presenter class name.
* @param string presenter name
* @return string class name
* @throws InvalidPresenterException
*/
public function getPresenterClass(& $name)
{
if (isset($this->cache[$name])) {
list($class, $name) = $this->cache[$name];
return $class;
}
if (!is_string($name) || !Nette\Utils\Strings::match($name, '#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*\z#')) {
throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");
}
$class = $this->formatPresenterClass($name);
if (!class_exists($class)) {
// internal autoloading
$file = $this->formatPresenterFile($name);
if (is_file($file) && is_readable($file)) {
call_user_func(function() use ($file) { require $file; });
}
if (!class_exists($class)) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found in '$file'.");
}
}
$reflection = new Nette\Reflection\ClassType($class);
$class = $reflection->getName();
if (!$reflection->implementsInterface('Nette\Application\IPresenter')) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");
}
if ($reflection->isAbstract()) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");
}
// canonicalize presenter name
$realName = $this->unformatPresenterClass($class);
if ($name !== $realName) {
if ($this->caseSensitive) {
throw new InvalidPresenterException("Cannot load presenter '$name', case mismatch. Real name is '$realName'.");
} else {
$this->cache[$name] = array($class, $realName);
$name = $realName;
}
} else {
$this->cache[$name] = array($class, $realName);
}
return $class;
}
/**
* Sets mapping as pairs [module => mask]
* @return self
*/
public function setMapping(array $mapping)
{
foreach ($mapping as $module => $mask) {
if (!preg_match('#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)\z#', $mask, $m)) {
throw new Nette\InvalidStateException("Invalid mapping mask '$mask'.");
}
$this->mapping[$module] = array($m[1], $m[2] ?: '*Module\\', $m[3]);
}
return $this;
}
/**
* Formats presenter class name from its name.
* @param string
* @return string
*/
public function formatPresenterClass($presenter)
{
$parts = explode(':', $presenter);
$mapping = isset($parts[1], $this->mapping[$parts[0]])
? $this->mapping[array_shift($parts)]
: $this->mapping['*'];
while ($part = array_shift($parts)) {
$mapping[0] .= str_replace('*', $part, $mapping[$parts ? 1 : 2]);
}
return $mapping[0];
}
/**
* Formats presenter name from class name.
* @param string
* @return string
*/
public function unformatPresenterClass($class)
{
foreach ($this->mapping as $module => $mapping) {
$mapping = str_replace(array('\\', '*'), array('\\\\', '(\w+)'), $mapping);
if (preg_match("#^\\\\?$mapping[0]((?:$mapping[1])*)$mapping[2]\\z#i", $class, $matches)) {
return ($module === '*' ? '' : $module . ':')
. preg_replace("#$mapping[1]#iA", '$1:', $matches[1]) . $matches[3];
}
}
}
/**
* Formats presenter class file name.
* @param string
* @return string
*/
public function formatPresenterFile($presenter)
{
$path = '/' . str_replace(':', 'Module/', $presenter);
return $this->baseDir . substr_replace($path, '/presenters', strrpos($path, '/'), 0) . 'Presenter.php';
}
}
Nette-2.1.0/Nette/Application/Request.php 100777 0 0 7314 12261522616 13403 0 name = $name;
$this->method = $method;
$this->params = $params;
$this->post = $post;
$this->files = $files;
$this->flags = $flags;
}
/**
* Sets the presenter name.
* @param string
* @return self
*/
public function setPresenterName($name)
{
$this->name = $name;
return $this;
}
/**
* Retrieve the presenter name.
* @return string
*/
public function getPresenterName()
{
return $this->name;
}
/**
* Sets variables provided to the presenter.
* @return self
*/
public function setParameters(array $params)
{
$this->params = $params;
return $this;
}
/**
* Returns all variables provided to the presenter (usually via URL).
* @return array
*/
public function getParameters()
{
return $this->params;
}
/**
* Sets variables provided to the presenter via POST.
* @return self
*/
public function setPost(array $params)
{
$this->post = $params;
return $this;
}
/**
* Returns all variables provided to the presenter via POST.
* @return array
*/
public function getPost()
{
return $this->post;
}
/**
* Sets all uploaded files.
* @return self
*/
public function setFiles(array $files)
{
$this->files = $files;
return $this;
}
/**
* Returns all uploaded files.
* @return array
*/
public function getFiles()
{
return $this->files;
}
/**
* Sets the method.
* @param string
* @return self
*/
public function setMethod($method)
{
$this->method = $method;
return $this;
}
/**
* Returns the method.
* @return string
*/
public function getMethod()
{
return $this->method;
}
/**
* Checks if the method is the given one.
* @param string
* @return bool
*/
public function isMethod($method)
{
return strcasecmp($this->method, $method) === 0;
}
/**
* Checks if the method is POST.
* @return bool
*/
public function isPost()
{
return strcasecmp($this->method, 'post') === 0;
}
/**
* Sets the flag.
* @param string
* @param bool
* @return self
*/
public function setFlag($flag, $value = TRUE)
{
$this->flags[$flag] = (bool) $value;
return $this;
}
/**
* Checks the flag.
* @param string
* @return bool
*/
public function hasFlag($flag)
{
return !empty($this->flags[$flag]);
}
}
Nette-2.1.0/Nette/Application/Responses/ 40777 0 0 0 12261522616 13116 5 Nette-2.1.0/Nette/Application/Responses/FileResponse.php 100777 0 0 5656 12261522616 16341 0 file = $file;
$this->name = $name ? $name : basename($file);
$this->contentType = $contentType ? $contentType : 'application/octet-stream';
}
/**
* Returns the path to a downloaded file.
* @return string
*/
public function getFile()
{
return $this->file;
}
/**
* Returns the file name.
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns the MIME content type of a downloaded file.
* @return string
*/
public function getContentType()
{
return $this->contentType;
}
/**
* Sends response to output.
* @return void
*/
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse)
{
$httpResponse->setContentType($this->contentType);
$httpResponse->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '"');
$filesize = $length = filesize($this->file);
$handle = fopen($this->file, 'r');
if ($this->resuming) {
$httpResponse->setHeader('Accept-Ranges', 'bytes');
if (preg_match('#^bytes=(\d*)-(\d*)\z#', $httpRequest->getHeader('Range'), $matches)) {
list(, $start, $end) = $matches;
if ($start === '') {
$start = max(0, $filesize - $end);
$end = $filesize - 1;
} elseif ($end === '' || $end > $filesize - 1) {
$end = $filesize - 1;
}
if ($end < $start) {
$httpResponse->setCode(416); // requested range not satisfiable
return;
}
$httpResponse->setCode(206);
$httpResponse->setHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $filesize);
$length = $end - $start + 1;
fseek($handle, $start);
} else {
$httpResponse->setHeader('Content-Range', 'bytes 0-' . ($filesize - 1) . '/' . $filesize);
}
}
$httpResponse->setHeader('Content-Length', $length);
while (!feof($handle) && $length > 0) {
echo $s = fread($handle, min(4e6, $length));
$length -= strlen($s);
}
fclose($handle);
}
}
Nette-2.1.0/Nette/Application/Responses/ForwardResponse.php 100777 0 0 1554 12261522616 17057 0 request = $request;
}
/**
* @return Nette\Application\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Sends response to output.
* @return void
*/
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse)
{
}
}
Nette-2.1.0/Nette/Application/Responses/JsonResponse.php 100777 0 0 3077 12261522616 16366 0 payload = $payload;
$this->contentType = $contentType ? $contentType : 'application/json';
}
/**
* @return array|\stdClass
*/
public function getPayload()
{
return $this->payload;
}
/**
* Returns the MIME content type of a downloaded file.
* @return string
*/
public function getContentType()
{
return $this->contentType;
}
/**
* Sends response to output.
* @return void
*/
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse)
{
$httpResponse->setContentType($this->contentType);
$httpResponse->setExpiration(FALSE);
echo Nette\Utils\Json::encode($this->payload);
}
}
Nette-2.1.0/Nette/Application/Responses/RedirectResponse.php 100777 0 0 2143 12261522616 17207 0 url = (string) $url;
$this->code = (int) $code;
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* @return int
*/
public function getCode()
{
return $this->code;
}
/**
* Sends response to output.
* @return void
*/
public function send(Http\IRequest $httpRequest, Http\IResponse $httpResponse)
{
$httpResponse->redirect($this->url, $this->code);
}
}
Nette-2.1.0/Nette/Application/Responses/TextResponse.php 100777 0 0 1705 12261522616 16375 0 source = $source;
}
/**
* @return mixed
*/
public function getSource()
{
return $this->source;
}
/**
* Sends response to output.
* @return void
*/
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse)
{
if ($this->source instanceof Nette\Templating\ITemplate) {
$this->source->render();
} else {
echo $this->source;
}
}
}
Nette-2.1.0/Nette/Application/Routers/ 40777 0 0 0 12261522616 12600 5 Nette-2.1.0/Nette/Application/Routers/CliRouter.php 100777 0 0 4445 12261522616 15330 0 defaults = $defaults;
}
/**
* Maps command line arguments to a Request object.
* @return Nette\Application\Request|NULL
*/
public function match(Nette\Http\IRequest $httpRequest)
{
if (empty($_SERVER['argv']) || !is_array($_SERVER['argv'])) {
return NULL;
}
$names = array(self::PRESENTER_KEY);
$params = $this->defaults;
$args = $_SERVER['argv'];
array_shift($args);
$args[] = '--';
foreach ($args as $arg) {
$opt = preg_replace('#/|-+#A', '', $arg);
if ($opt === $arg) {
if (isset($flag) || $flag = array_shift($names)) {
$params[$flag] = $arg;
} else {
$params[] = $arg;
}
$flag = NULL;
continue;
}
if (isset($flag)) {
$params[$flag] = TRUE;
$flag = NULL;
}
if ($opt !== '') {
$pair = explode('=', $opt, 2);
if (isset($pair[1])) {
$params[$pair[0]] = $pair[1];
} else {
$flag = $pair[0];
}
}
}
if (!isset($params[self::PRESENTER_KEY])) {
throw new Nette\InvalidStateException('Missing presenter & action in route definition.');
}
$presenter = $params[self::PRESENTER_KEY];
if ($a = strrpos($presenter, ':')) {
$params[self::PRESENTER_KEY] = substr($presenter, $a + 1);
$presenter = substr($presenter, 0, $a);
}
return new Application\Request(
$presenter,
'CLI',
$params
);
}
/**
* This router is only unidirectional.
* @return NULL
*/
public function constructUrl(Application\Request $appRequest, Nette\Http\Url $refUrl)
{
return NULL;
}
/**
* Returns default values.
* @return array
*/
public function getDefaults()
{
return $this->defaults;
}
}
Nette-2.1.0/Nette/Application/Routers/Route.php 100777 0 0 53713 12261522616 14540 0 array( // default style for path parameters
self::PATTERN => '[^/]+',
self::FILTER_IN => 'rawurldecode',
self::FILTER_OUT => array(__CLASS__, 'param2path'),
),
'?#' => array( // default style for query parameters
),
'module' => array(
self::PATTERN => '[a-z][a-z0-9.-]*',
self::FILTER_IN => array(__CLASS__, 'path2presenter'),
self::FILTER_OUT => array(__CLASS__, 'presenter2path'),
),
'presenter' => array(
self::PATTERN => '[a-z][a-z0-9.-]*',
self::FILTER_IN => array(__CLASS__, 'path2presenter'),
self::FILTER_OUT => array(__CLASS__, 'presenter2path'),
),
'action' => array(
self::PATTERN => '[a-z][a-z0-9-]*',
self::FILTER_IN => array(__CLASS__, 'path2action'),
self::FILTER_OUT => array(__CLASS__, 'action2path'),
),
'?module' => array(
),
'?presenter' => array(
),
'?action' => array(
),
);
/** @var string */
private $mask;
/** @var array */
private $sequence;
/** @var string regular expression pattern */
private $re;
/** @var array of [value & fixity, filterIn, filterOut] */
private $metadata = array();
/** @var array */
private $xlat;
/** @var int HOST, PATH, RELATIVE */
private $type;
/** @var int */
private $flags;
/**
* @param string URL mask, e.g. '//'
* @param array|string default values or metadata
* @param int flags
*/
public function __construct($mask, $metadata = array(), $flags = 0)
{
if (is_string($metadata)) {
$a = strrpos($metadata, ':');
if (!$a) {
throw new Nette\InvalidArgumentException("Second argument must be array or string in format Presenter:action, '$metadata' given.");
}
$metadata = array(
self::PRESENTER_KEY => substr($metadata, 0, $a),
'action' => $a === strlen($metadata) - 1 ? NULL : substr($metadata, $a + 1),
);
} elseif ($metadata instanceof \Closure || $metadata instanceof Nette\Callback) {
$metadata = array(
self::PRESENTER_KEY => 'Nette:Micro',
'callback' => $metadata,
);
}
$this->flags = $flags | static::$defaultFlags;
$this->setMask($mask, $metadata);
}
/**
* Maps HTTP request to a Request object.
* @return Nette\Application\Request|NULL
*/
public function match(Nette\Http\IRequest $httpRequest)
{
// combine with precedence: mask (params in URL-path), fixity, query, (post,) defaults
// 1) URL MASK
$url = $httpRequest->getUrl();
$re = $this->re;
if ($this->type === self::HOST) {
$path = '//' . $url->getHost() . $url->getPath();
$host = array_reverse(explode('.', $url->getHost()));
$re = strtr($re, array(
'/%basePath%/' => preg_quote($url->getBasePath(), '#'),
'%tld%' => $host[0],
'%domain%' => isset($host[1]) ? "$host[1]\\.$host[0]" : $host[0],
));
} elseif ($this->type === self::RELATIVE) {
$basePath = $url->getBasePath();
if (strncmp($url->getPath(), $basePath, strlen($basePath)) !== 0) {
return NULL;
}
$path = (string) substr($url->getPath(), strlen($basePath));
} else {
$path = $url->getPath();
}
if ($path !== '') {
$path = rtrim($path, '/') . '/';
}
if (!$matches = Strings::match($path, $re)) {
// stop, not matched
return NULL;
}
// deletes numeric keys, restore '-' chars
$params = array();
foreach ($matches as $k => $v) {
if (is_string($k) && $v !== '') {
$params[str_replace('___', '-', $k)] = $v; // trick
}
}
// 2) CONSTANT FIXITY
foreach ($this->metadata as $name => $meta) {
if (isset($params[$name])) {
//$params[$name] = $this->flags & self::CASE_SENSITIVE === 0 ? strtolower($params[$name]) : */$params[$name]; // strtolower damages UTF-8
} elseif (isset($meta['fixity']) && $meta['fixity'] !== self::OPTIONAL) {
$params[$name] = NULL; // cannot be overwriten in 3) and detected by isset() in 4)
}
}
// 3) QUERY
if ($this->xlat) {
$params += self::renameKeys($httpRequest->getQuery(), array_flip($this->xlat));
} else {
$params += $httpRequest->getQuery();
}
// 4) APPLY FILTERS & FIXITY
foreach ($this->metadata as $name => $meta) {
if (isset($params[$name])) {
if (!is_scalar($params[$name])) {
} elseif (isset($meta[self::FILTER_TABLE][$params[$name]])) { // applies filterTable only to scalar parameters
$params[$name] = $meta[self::FILTER_TABLE][$params[$name]];
} elseif (isset($meta[self::FILTER_TABLE]) && !empty($meta[self::FILTER_STRICT])) {
return NULL; // rejected by filterTable
} elseif (isset($meta[self::FILTER_IN])) { // applies filterIn only to scalar parameters
$params[$name] = call_user_func($meta[self::FILTER_IN], (string) $params[$name]);
if ($params[$name] === NULL && !isset($meta['fixity'])) {
return NULL; // rejected by filter
}
}
} elseif (isset($meta['fixity'])) {
$params[$name] = $meta[self::VALUE];
}
}
if (isset($this->metadata[NULL][self::FILTER_IN])) {
$params = call_user_func($this->metadata[NULL][self::FILTER_IN], $params);
if ($params === NULL) {
return NULL;
}
}
// 5) BUILD Request
if (!isset($params[self::PRESENTER_KEY])) {
throw new Nette\InvalidStateException('Missing presenter in route definition.');
} elseif (!is_string($params[self::PRESENTER_KEY])) {
return NULL;
}
if (isset($this->metadata[self::MODULE_KEY])) {
if (!isset($params[self::MODULE_KEY])) {
throw new Nette\InvalidStateException('Missing module in route definition.');
}
$presenter = $params[self::MODULE_KEY] . ':' . $params[self::PRESENTER_KEY];
unset($params[self::MODULE_KEY], $params[self::PRESENTER_KEY]);
} else {
$presenter = $params[self::PRESENTER_KEY];
unset($params[self::PRESENTER_KEY]);
}
return new Application\Request(
$presenter,
$httpRequest->getMethod(),
$params,
$httpRequest->getPost(),
$httpRequest->getFiles(),
array(Application\Request::SECURED => $httpRequest->isSecured())
);
}
/**
* Constructs absolute URL from Request object.
* @return string|NULL
*/
public function constructUrl(Application\Request $appRequest, Nette\Http\Url $refUrl)
{
if ($this->flags & self::ONE_WAY) {
return NULL;
}
$params = $appRequest->getParameters();
$metadata = $this->metadata;
$presenter = $appRequest->getPresenterName();
$params[self::PRESENTER_KEY] = $presenter;
if (isset($metadata[NULL][self::FILTER_OUT])) {
$params = call_user_func($metadata[NULL][self::FILTER_OUT], $params);
if ($params === NULL) {
return NULL;
}
}
if (isset($metadata[self::MODULE_KEY])) { // try split into module and [submodule:]presenter parts
$module = $metadata[self::MODULE_KEY];
if (isset($module['fixity']) && strncasecmp($presenter, $module[self::VALUE] . ':', strlen($module[self::VALUE]) + 1) === 0) {
$a = strlen($module[self::VALUE]);
} else {
$a = strrpos($presenter, ':');
}
if ($a === FALSE) {
$params[self::MODULE_KEY] = '';
} else {
$params[self::MODULE_KEY] = substr($presenter, 0, $a);
$params[self::PRESENTER_KEY] = substr($presenter, $a + 1);
}
}
foreach ($metadata as $name => $meta) {
if (!isset($params[$name])) {
continue; // retains NULL values
}
if (isset($meta['fixity'])) {
if ($params[$name] === FALSE) {
$params[$name] = '0';
}
if (is_scalar($params[$name]) ? strcasecmp($params[$name], $meta[self::VALUE]) === 0
: $params[$name] === $meta[self::VALUE]
) { // remove default values; NULL values are retain
unset($params[$name]);
continue;
} elseif ($meta['fixity'] === self::CONSTANT) {
return NULL; // missing or wrong parameter '$name'
}
}
if (is_scalar($params[$name]) && isset($meta['filterTable2'][$params[$name]])) {
$params[$name] = $meta['filterTable2'][$params[$name]];
} elseif (isset($meta['filterTable2']) && !empty($meta[self::FILTER_STRICT])) {
return NULL;
} elseif (isset($meta[self::FILTER_OUT])) {
$params[$name] = call_user_func($meta[self::FILTER_OUT], $params[$name]);
}
if (isset($meta[self::PATTERN]) && !preg_match($meta[self::PATTERN], rawurldecode($params[$name]))) {
return NULL; // pattern not match
}
}
// compositing path
$sequence = $this->sequence;
$brackets = array();
$required = NULL; // NULL for auto-optional
$url = '';
$i = count($sequence) - 1;
do {
$url = $sequence[$i] . $url;
if ($i === 0) {
break;
}
$i--;
$name = $sequence[$i]; $i--; // parameter name
if ($name === ']') { // opening optional part
$brackets[] = $url;
} elseif ($name[0] === '[') { // closing optional part
$tmp = array_pop($brackets);
if ($required < count($brackets) + 1) { // is this level optional?
if ($name !== '[!') { // and not "required"-optional
$url = $tmp;
}
} else {
$required = count($brackets);
}
} elseif ($name[0] === '?') { // "foo" parameter
continue;
} elseif (isset($params[$name]) && $params[$name] != '') { // intentionally ==
$required = count($brackets); // make this level required
$url = $params[$name] . $url;
unset($params[$name]);
} elseif (isset($metadata[$name]['fixity'])) { // has default value?
if ($required === NULL && !$brackets) { // auto-optional
$url = '';
} else {
$url = $metadata[$name]['defOut'] . $url;
}
} else {
return NULL; // missing parameter '$name'
}
} while (TRUE);
// absolutize path
if ($this->type === self::RELATIVE) {
$url = '//' . $refUrl->getAuthority() . $refUrl->getBasePath() . $url;
} elseif ($this->type === self::PATH) {
$url = '//' . $refUrl->getAuthority() . $url;
} else {
$host = array_reverse(explode('.', $refUrl->getHost()));
$url = strtr($url, array(
'/%basePath%/' => $refUrl->getBasePath(),
'%tld%' => $host[0],
'%domain%' => isset($host[1]) ? "$host[1].$host[0]" : $host[0],
));
}
if (strpos($url, '//', 2) !== FALSE) {
return NULL; // TODO: implement counterpart in match() ?
}
$url = ($this->flags & self::SECURED ? 'https:' : 'http:') . $url;
// build query string
if ($this->xlat) {
$params = self::renameKeys($params, $this->xlat);
}
$sep = ini_get('arg_separator.input');
$query = http_build_query($params, '', $sep ? $sep[0] : '&');
if ($query != '') { // intentionally ==
$url .= '?' . $query;
}
return $url;
}
/**
* Parse mask and array of default values; initializes object.
* @param string
* @param array
* @return void
*/
private function setMask($mask, array $metadata)
{
$this->mask = $mask;
// detect '//host/path' vs. '/abs. path' vs. 'relative path'
if (substr($mask, 0, 2) === '//') {
$this->type = self::HOST;
} elseif (substr($mask, 0, 1) === '/') {
$this->type = self::PATH;
} else {
$this->type = self::RELATIVE;
}
foreach ($metadata as $name => $meta) {
if (!is_array($meta)) {
$metadata[$name] = array(self::VALUE => $meta, 'fixity' => self::CONSTANT);
} elseif (array_key_exists(self::VALUE, $meta)) {
$metadata[$name]['fixity'] = self::CONSTANT;
}
}
// PARSE MASK
// or [ or ] or ?...
$parts = Strings::split($mask, '/<([^>#= ]+)(=[^># ]*)? *([^>#]*)(#?[^>\[\]]*)>|(\[!?|\]|\s*\?.*)/');
$this->xlat = array();
$i = count($parts) - 1;
// PARSE QUERY PART OF MASK
if (isset($parts[$i - 1]) && substr(ltrim($parts[$i - 1]), 0, 1) === '?') {
// name=
$matches = Strings::matchAll($parts[$i - 1], '/(?:([a-zA-Z0-9_.-]+)=)?<([^># ]+) *([^>#]*)(#?[^>]*)>/');
foreach ($matches as $match) {
list(, $param, $name, $pattern, $class) = $match; // $pattern is not used
if ($class !== '') {
if (!isset(static::$styles[$class])) {
throw new Nette\InvalidStateException("Parameter '$name' has '$class' flag, but Route::\$styles['$class'] is not set.");
}
$meta = static::$styles[$class];
} elseif (isset(static::$styles['?' . $name])) {
$meta = static::$styles['?' . $name];
} else {
$meta = static::$styles['?#'];
}
if (isset($metadata[$name])) {
$meta = $metadata[$name] + $meta;
}
if (array_key_exists(self::VALUE, $meta)) {
$meta['fixity'] = self::OPTIONAL;
}
unset($meta['pattern']);
$meta['filterTable2'] = empty($meta[self::FILTER_TABLE]) ? NULL : array_flip($meta[self::FILTER_TABLE]);
$metadata[$name] = $meta;
if ($param !== '') {
$this->xlat[$name] = $param;
}
}
$i -= 6;
}
// PARSE PATH PART OF MASK
$brackets = 0; // optional level
$re = '';
$sequence = array();
$autoOptional = TRUE;
do {
array_unshift($sequence, $parts[$i]);
$re = preg_quote($parts[$i], '#') . $re;
if ($i === 0) {
break;
}
$i--;
$part = $parts[$i]; // [ or ]
if ($part === '[' || $part === ']' || $part === '[!') {
$brackets += $part[0] === '[' ? -1 : 1;
if ($brackets < 0) {
throw new Nette\InvalidArgumentException("Unexpected '$part' in mask '$mask'.");
}
array_unshift($sequence, $part);
$re = ($part[0] === '[' ? '(?:' : ')?') . $re;
$i -= 5;
continue;
}
$class = $parts[$i]; $i--; // validation class
$pattern = trim($parts[$i]); $i--; // validation condition (as regexp)
$default = $parts[$i]; $i--; // default value
$name = $parts[$i]; $i--; // parameter name
array_unshift($sequence, $name);
if ($name[0] === '?') { // "foo" parameter
$name = substr($name, 1);
$re = $pattern ? '(?:' . preg_quote($name, '#') . "|$pattern)$re" : preg_quote($name, '#') . $re;
$sequence[1] = $name . $sequence[1];
continue;
}
// check name (limitation by regexp)
if (preg_match('#[^a-z0-9_-]#i', $name)) {
throw new Nette\InvalidArgumentException("Parameter name must be alphanumeric string due to limitations of PCRE, '$name' given.");
}
// pattern, condition & metadata
if ($class !== '') {
if (!isset(static::$styles[$class])) {
throw new Nette\InvalidStateException("Parameter '$name' has '$class' flag, but Route::\$styles['$class'] is not set.");
}
$meta = static::$styles[$class];
} elseif (isset(static::$styles[$name])) {
$meta = static::$styles[$name];
} else {
$meta = static::$styles['#'];
}
if (isset($metadata[$name])) {
$meta = $metadata[$name] + $meta;
}
if ($pattern == '' && isset($meta[self::PATTERN])) {
$pattern = $meta[self::PATTERN];
}
if ($default !== '') {
$meta[self::VALUE] = (string) substr($default, 1);
$meta['fixity'] = self::PATH_OPTIONAL;
}
$meta['filterTable2'] = empty($meta[self::FILTER_TABLE]) ? NULL : array_flip($meta[self::FILTER_TABLE]);
if (array_key_exists(self::VALUE, $meta)) {
if (isset($meta['filterTable2'][$meta[self::VALUE]])) {
$meta['defOut'] = $meta['filterTable2'][$meta[self::VALUE]];
} elseif (isset($meta[self::FILTER_OUT])) {
$meta['defOut'] = call_user_func($meta[self::FILTER_OUT], $meta[self::VALUE]);
} else {
$meta['defOut'] = $meta[self::VALUE];
}
}
$meta[self::PATTERN] = "#(?:$pattern)\\z#A" . ($this->flags & self::CASE_SENSITIVE ? '' : 'iu');
// include in expression
$re = '(?P<' . str_replace('-', '___', $name) . '>(?U)' . $pattern . ')' . $re; // str_replace is dirty trick to enable '-' in parameter name
if ($brackets) { // is in brackets?
if (!isset($meta[self::VALUE])) {
$meta[self::VALUE] = $meta['defOut'] = NULL;
}
$meta['fixity'] = self::PATH_OPTIONAL;
} elseif (!$autoOptional) {
unset($meta['fixity']);
} elseif (isset($meta['fixity'])) { // auto-optional
$re = '(?:' . $re . ')?';
$meta['fixity'] = self::PATH_OPTIONAL;
} else {
$autoOptional = FALSE;
}
$metadata[$name] = $meta;
} while (TRUE);
if ($brackets) {
throw new Nette\InvalidArgumentException("Missing closing ']' in mask '$mask'.");
}
$this->re = '#' . $re . '/?\z#A' . ($this->flags & self::CASE_SENSITIVE ? '' : 'iu');
$this->metadata = $metadata;
$this->sequence = $sequence;
}
/**
* Returns mask.
* @return string
*/
public function getMask()
{
return $this->mask;
}
/**
* Returns default values.
* @return array
*/
public function getDefaults()
{
$defaults = array();
foreach ($this->metadata as $name => $meta) {
if (isset($meta['fixity'])) {
$defaults[$name] = $meta[self::VALUE];
}
}
return $defaults;
}
/**
* Returns flags.
* @return int
*/
public function getFlags()
{
return $this->flags;
}
/********************* Utilities ****************d*g**/
/**
* Proprietary cache aim.
* @internal
* @return string|FALSE
*/
public function getTargetPresenter()
{
if ($this->flags & self::ONE_WAY) {
return FALSE;
}
$m = $this->metadata;
$module = '';
if (isset($m[self::MODULE_KEY])) {
if (isset($m[self::MODULE_KEY]['fixity']) && $m[self::MODULE_KEY]['fixity'] === self::CONSTANT) {
$module = $m[self::MODULE_KEY][self::VALUE] . ':';
} else {
return NULL;
}
}
if (isset($m[self::PRESENTER_KEY]['fixity']) && $m[self::PRESENTER_KEY]['fixity'] === self::CONSTANT) {
return $module . $m[self::PRESENTER_KEY][self::VALUE];
}
return NULL;
}
/**
* Rename keys in array.
* @param array
* @param array
* @return array
*/
private static function renameKeys($arr, $xlat)
{
if (empty($xlat)) {
return $arr;
}
$res = array();
$occupied = array_flip($xlat);
foreach ($arr as $k => $v) {
if (isset($xlat[$k])) {
$res[$xlat[$k]] = $v;
} elseif (!isset($occupied[$k])) {
$res[$k] = $v;
}
}
return $res;
}
/********************* Inflectors ****************d*g**/
/**
* camelCaseAction name -> dash-separated.
* @param string
* @return string
*/
private static function action2path($s)
{
$s = preg_replace('#(.)(?=[A-Z])#', '$1-', $s);
$s = strtolower($s);
$s = rawurlencode($s);
return $s;
}
/**
* dash-separated -> camelCaseAction name.
* @param string
* @return string
*/
private static function path2action($s)
{
$s = strtolower($s);
$s = preg_replace('#-(?=[a-z])#', ' ', $s);
$s = substr(ucwords('x' . $s), 1);
//$s = lcfirst(ucwords($s));
$s = str_replace(' ', '', $s);
return $s;
}
/**
* PascalCase:Presenter name -> dash-and-dot-separated.
* @param string
* @return string
*/
private static function presenter2path($s)
{
$s = strtr($s, ':', '.');
$s = preg_replace('#([^.])(?=[A-Z])#', '$1-', $s);
$s = strtolower($s);
$s = rawurlencode($s);
return $s;
}
/**
* dash-and-dot-separated -> PascalCase:Presenter name.
* @param string
* @return string
*/
private static function path2presenter($s)
{
$s = strtolower($s);
$s = preg_replace('#([.-])(?=[a-z])#', '$1 ', $s);
$s = ucwords($s);
$s = str_replace('. ', ':', $s);
$s = str_replace('- ', '', $s);
return $s;
}
/**
* Url encode.
* @param string
* @return string
*/
private static function param2path($s)
{
return str_replace('%2F', '/', rawurlencode($s));
}
/********************* Route::$styles manipulator ****************d*g**/
/**
* Creates new style.
* @param string style name (#style, urlParameter, ?queryParameter)
* @param string optional parent style name
* @return void
*/
public static function addStyle($style, $parent = '#')
{
if (isset(static::$styles[$style])) {
throw new Nette\InvalidArgumentException("Style '$style' already exists.");
}
if ($parent !== NULL) {
if (!isset(static::$styles[$parent])) {
throw new Nette\InvalidArgumentException("Parent style '$parent' doesn't exist.");
}
static::$styles[$style] = static::$styles[$parent];
} else {
static::$styles[$style] = array();
}
}
/**
* Changes style property value.
* @param string style name (#style, urlParameter, ?queryParameter)
* @param string property name (Route::PATTERN, Route::FILTER_IN, Route::FILTER_OUT, Route::FILTER_TABLE)
* @param mixed property value
* @return void
*/
public static function setStyleProperty($style, $key, $value)
{
if (!isset(static::$styles[$style])) {
throw new Nette\InvalidArgumentException("Style '$style' doesn't exist.");
}
static::$styles[$style][$key] = $value;
}
}
Nette-2.1.0/Nette/Application/Routers/RouteList.php 100777 0 0 5576 12261522616 15360 0 module = $module ? $module . ':' : '';
}
/**
* Maps HTTP request to a Request object.
* @return Nette\Application\Request|NULL
*/
public function match(Nette\Http\IRequest $httpRequest)
{
foreach ($this as $route) {
$appRequest = $route->match($httpRequest);
if ($appRequest !== NULL) {
$name = $appRequest->getPresenterName();
if (strncmp($name, 'Nette:', 6)) {
$appRequest->setPresenterName($this->module . $name);
}
return $appRequest;
}
}
return NULL;
}
/**
* Constructs absolute URL from Request object.
* @return string|NULL
*/
public function constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl)
{
if ($this->cachedRoutes === NULL) {
$routes = array();
$routes['*'] = array();
foreach ($this as $route) {
$presenter = $route instanceof Route ? $route->getTargetPresenter() : NULL;
if ($presenter === FALSE) {
continue;
}
if (is_string($presenter)) {
$presenter = strtolower($presenter);
if (!isset($routes[$presenter])) {
$routes[$presenter] = $routes['*'];
}
$routes[$presenter][] = $route;
} else {
foreach ($routes as $id => $foo) {
$routes[$id][] = $route;
}
}
}
$this->cachedRoutes = $routes;
}
if ($this->module) {
if (strncasecmp($tmp = $appRequest->getPresenterName(), $this->module, strlen($this->module)) === 0) {
$appRequest = clone $appRequest;
$appRequest->setPresenterName(substr($tmp, strlen($this->module)));
} else {
return NULL;
}
}
$presenter = strtolower($appRequest->getPresenterName());
if (!isset($this->cachedRoutes[$presenter])) {
$presenter = '*';
}
foreach ($this->cachedRoutes[$presenter] as $route) {
$url = $route->constructUrl($appRequest, $refUrl);
if ($url !== NULL) {
return $url;
}
}
return NULL;
}
/**
* Adds the router.
* @param mixed
* @param Nette\Application\IRouter
* @return void
*/
public function offsetSet($index, $route)
{
if (!$route instanceof Nette\Application\IRouter) {
throw new Nette\InvalidArgumentException("Argument must be IRouter descendant.");
}
parent::offsetSet($index, $route);
}
/**
* @return string
*/
public function getModule()
{
return $this->module;
}
}
Nette-2.1.0/Nette/Application/Routers/SimpleRouter.php 100777 0 0 7031 12261522616 16044 0 substr($defaults, 0, $a),
'action' => $a === strlen($defaults) - 1 ? Application\UI\Presenter::DEFAULT_ACTION : substr($defaults, $a + 1),
);
}
if (isset($defaults[self::MODULE_KEY])) {
$this->module = $defaults[self::MODULE_KEY] . ':';
unset($defaults[self::MODULE_KEY]);
}
$this->defaults = $defaults;
$this->flags = $flags;
}
/**
* Maps HTTP request to a Request object.
* @return Nette\Application\Request|NULL
*/
public function match(Nette\Http\IRequest $httpRequest)
{
if ($httpRequest->getUrl()->getPathInfo() !== '') {
return NULL;
}
// combine with precedence: get, (post,) defaults
$params = $httpRequest->getQuery();
$params += $this->defaults;
if (!isset($params[self::PRESENTER_KEY]) || !is_string($params[self::PRESENTER_KEY])) {
return NULL;
}
$presenter = $this->module . $params[self::PRESENTER_KEY];
unset($params[self::PRESENTER_KEY]);
return new Application\Request(
$presenter,
$httpRequest->getMethod(),
$params,
$httpRequest->getPost(),
$httpRequest->getFiles(),
array(Application\Request::SECURED => $httpRequest->isSecured())
);
}
/**
* Constructs absolute URL from Request object.
* @return string|NULL
*/
public function constructUrl(Application\Request $appRequest, Nette\Http\Url $refUrl)
{
if ($this->flags & self::ONE_WAY) {
return NULL;
}
$params = $appRequest->getParameters();
// presenter name
$presenter = $appRequest->getPresenterName();
if (strncasecmp($presenter, $this->module, strlen($this->module)) === 0) {
$params[self::PRESENTER_KEY] = substr($presenter, strlen($this->module));
} else {
return NULL;
}
// remove default values; NULL values are retain
foreach ($this->defaults as $key => $value) {
if (isset($params[$key]) && $params[$key] == $value) { // intentionally ==
unset($params[$key]);
}
}
$url = ($this->flags & self::SECURED ? 'https://' : 'http://') . $refUrl->getAuthority() . $refUrl->getPath();
$sep = ini_get('arg_separator.input');
$query = http_build_query($params, '', $sep ? $sep[0] : '&');
if ($query != '') { // intentionally ==
$url .= '?' . $query;
}
return $url;
}
/**
* Returns default values.
* @return array
*/
public function getDefaults()
{
return $this->defaults;
}
/**
* Returns flags.
* @return int
*/
public function getFlags()
{
return $this->flags;
}
}
Nette-2.1.0/Nette/Application/templates/ 40777 0 0 0 12261522616 13133 5 Nette-2.1.0/Nette/Application/templates/error.phtml 100777 0 0 3106 12261522616 15432 0 array('Oops...', 'Your browser sent a request that this server could not understand or process.'),
403 => array('Access Denied', 'You do not have permission to view this page. Please try contact the web site administrator if you believe you should be able to view this page.'),
404 => array('Page Not Found', 'The page you requested could not be found. It is possible that the address is incorrect, or that the page no longer exists. Please use a search engine to find what you are looking for.'),
405 => array('Method Not Allowed', 'The requested method is not allowed for the URL.'),
410 => array('Page Not Found', 'The page you requested has been taken off the site. We apologize for the inconvenience.'),
500 => array('Server Error', 'We\'re sorry! The server encountered an internal error and was unable to complete your request. Please try again later.'),
);
$message = isset($messages[$code]) ? $messages[$code] : $messages[0];
?>
error
Nette-2.1.0/Nette/Application/UI/ 40777 0 0 0 12261522617 11453 5 Nette-2.1.0/Nette/Application/UI/BadSignalException.php 100777 0 0 605 12261522616 15747 0 template === NULL) {
$value = $this->createTemplate();
if (!$value instanceof Nette\Templating\ITemplate && $value !== NULL) {
$class2 = get_class($value); $class = get_class($this);
throw new Nette\UnexpectedValueException("Object returned by $class::createTemplate() must be instance of Nette\\Templating\\ITemplate, '$class2' given.");
}
$this->template = $value;
}
return $this->template;
}
/**
* @param string|NULL
* @return Nette\Templating\ITemplate
*/
protected function createTemplate($class = NULL)
{
$template = $class ? new $class : new Nette\Templating\FileTemplate;
$presenter = $this->getPresenter(FALSE);
$template->onPrepareFilters[] = $this->templatePrepareFilters;
$template->registerHelperLoader('Nette\Templating\Helpers::loader');
// default parameters
$template->control = $template->_control = $this;
$template->presenter = $template->_presenter = $presenter;
if ($presenter instanceof Presenter) {
$template->setCacheStorage($presenter->getContext()->getService('nette.templateCacheStorage'));
$template->user = $presenter->getUser();
$template->netteHttpResponse = $presenter->getHttpResponse();
$template->netteCacheStorage = $presenter->getContext()->getByType('Nette\Caching\IStorage');
$template->baseUri = $template->baseUrl = rtrim($presenter->getHttpRequest()->getUrl()->getBaseUrl(), '/');
$template->basePath = preg_replace('#https?://[^/]+#A', '', $template->baseUrl);
// flash message
if ($presenter->hasFlashSession()) {
$id = $this->getParameterId('flash');
$template->flashes = $presenter->getFlashSession()->$id;
}
}
if (!isset($template->flashes) || !is_array($template->flashes)) {
$template->flashes = array();
}
return $template;
}
/**
* Descendant can override this method to customize template compile-time filters.
* @param Nette\Templating\Template
* @return void
*/
public function templatePrepareFilters($template)
{
$template->registerFilter($this->getPresenter()->getContext()->createService('nette.latte'));
}
/**
* Saves the message to template, that can be displayed after redirect.
* @param string
* @param string
* @return \stdClass
*/
public function flashMessage($message, $type = 'info')
{
$id = $this->getParameterId('flash');
$messages = $this->getPresenter()->getFlashSession()->$id;
$messages[] = $flash = (object) array(
'message' => $message,
'type' => $type,
);
$this->getTemplate()->flashes = $messages;
$this->getPresenter()->getFlashSession()->$id = $messages;
return $flash;
}
/********************* rendering ****************d*g**/
/**
* Forces control or its snippet to repaint.
* @return void
*/
public function redrawControl($snippet = NULL, $redraw = TRUE)
{
if ($redraw) {
$this->invalidSnippets[$snippet] = TRUE;
} elseif ($snippet === NULL) {
$this->invalidSnippets = array();
} else {
unset($this->invalidSnippets[$snippet]);
}
}
/** @deprecated */
function invalidateControl($snippet = NULL)
{
$this->redrawControl($snippet);
}
/** @deprecated */
function validateControl($snippet = NULL)
{
$this->redrawControl($snippet, FALSE);
}
/**
* Is required to repaint the control or its snippet?
* @param string snippet name
* @return bool
*/
public function isControlInvalid($snippet = NULL)
{
if ($snippet === NULL) {
if (count($this->invalidSnippets) > 0) {
return TRUE;
} else {
$queue = array($this);
do {
foreach (array_shift($queue)->getComponents() as $component) {
if ($component instanceof IRenderable) {
if ($component->isControlInvalid()) {
// $this->invalidSnippets['__child'] = TRUE; // as cache
return TRUE;
}
} elseif ($component instanceof Nette\ComponentModel\IContainer) {
$queue[] = $component;
}
}
} while ($queue);
return FALSE;
}
} else {
return isset($this->invalidSnippets[NULL]) || isset($this->invalidSnippets[$snippet]);
}
}
/**
* Returns snippet HTML ID.
* @param string snippet name
* @return string
*/
public function getSnippetId($name = NULL)
{
// HTML 4 ID & NAME: [A-Za-z][A-Za-z0-9:_.-]*
return 'snippet-' . $this->getUniqueId() . '-' . $name;
}
}
Nette-2.1.0/Nette/Application/UI/Form.php 100777 0 0 6170 12261522616 13172 0 monitor('Nette\Application\UI\Presenter');
if ($parent !== NULL) {
$parent->addComponent($this, $name);
}
}
/**
* Returns the presenter where this component belongs to.
* @param bool throw exception if presenter doesn't exist?
* @return Presenter|NULL
*/
public function getPresenter($need = TRUE)
{
return $this->lookup('Nette\Application\UI\Presenter', $need);
}
/**
* This method will be called when the component (or component's parent)
* becomes attached to a monitored object. Do not call this method yourself.
* @param Nette\ComponentModel\IComponent
* @return void
*/
protected function attached($presenter)
{
if ($presenter instanceof Presenter) {
$name = $this->lookupPath('Nette\Application\UI\Presenter');
if (!isset($this->getElementPrototype()->id)) {
$this->getElementPrototype()->id = 'frm-' . $name;
}
if (!$this->getAction()) {
$this->setAction(new Link(
$presenter,
$name . self::NAME_SEPARATOR . 'submit!',
array()
));
}
if (iterator_count($this->getControls()) && $this->isSubmitted()) {
foreach ($this->getControls() as $control) {
if (!$control->isDisabled()) {
$control->loadHttpData();
}
}
}
}
parent::attached($presenter);
}
/**
* Tells if the form is anchored.
* @return bool
*/
public function isAnchored()
{
return (bool) $this->getPresenter(FALSE);
}
/**
* Internal: returns submitted HTTP data or NULL when form was not submitted.
* @return array|NULL
*/
protected function receiveHttpData()
{
$presenter = $this->getPresenter();
if (!$presenter->isSignalReceiver($this, 'submit')) {
return;
}
$isPost = $this->getMethod() === self::POST;
$request = $presenter->getRequest();
if ($request->isMethod('forward') || $request->isMethod('post') !== $isPost) {
return;
}
if ($isPost) {
return Nette\Utils\Arrays::mergeTree($request->getPost(), $request->getFiles());
} else {
return $request->getParameters();
}
}
/********************* interface ISignalReceiver ****************d*g**/
/**
* This method is called by presenter.
* @param string
* @return void
*/
public function signalReceived($signal)
{
if ($signal === 'submit') {
if (!$this->getPresenter()->getRequest()->hasFlag(Nette\Application\Request::RESTORED)) {
$this->fireEvents();
}
} else {
$class = get_class($this);
throw new BadSignalException("Missing handler for signal '$signal' in $class.");
}
}
}
Nette-2.1.0/Nette/Application/UI/InvalidLinkException.php 100777 0 0 501 12261522616 16322 0 component = $component;
$this->destination = $destination;
$this->params = $params;
}
/**
* Returns link destination.
* @return string
*/
public function getDestination()
{
return $this->destination;
}
/**
* Changes link parameter.
* @param string
* @param mixed
* @return self
*/
public function setParameter($key, $value)
{
$this->params[$key] = $value;
return $this;
}
/**
* Returns link parameter.
* @param string
* @return mixed
*/
public function getParameter($key)
{
return isset($this->params[$key]) ? $this->params[$key] : NULL;
}
/**
* Returns link parameters.
* @return array
*/
public function getParameters()
{
return $this->params;
}
/**
* Converts link to URL.
* @return string
*/
public function __toString()
{
try {
return (string) $this->component->link($this->destination, $this->params);
} catch (\Exception $e) {
trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
}
}
}
Nette-2.1.0/Nette/Application/UI/Multiplier.php 100777 0 0 1140 12261522617 14406 0 factory = Nette\Utils\Callback::check($factory);
}
protected function createComponent($name)
{
return call_user_func($this->factory, $name, $this);
}
}
Nette-2.1.0/Nette/Application/UI/Presenter.php 100777 0 0 107345 12261522617 14305 0 request;
}
/**
* Returns self.
* @return Presenter
*/
public function getPresenter($need = TRUE)
{
return $this;
}
/**
* Returns a name that uniquely identifies component.
* @return string
*/
public function getUniqueId()
{
return '';
}
/********************* interface IPresenter ****************d*g**/
/**
* @return Nette\Application\IResponse
*/
public function run(Application\Request $request)
{
try {
// STARTUP
$this->request = $request;
$this->payload = new \stdClass;
$this->setParent($this->getParent(), $request->getPresenterName());
if (!$this->httpResponse->isSent()) {
$this->httpResponse->addHeader('Vary', 'X-Requested-With');
}
$this->initGlobalParameters();
$this->checkRequirements($this->getReflection());
$this->startup();
if (!$this->startupCheck) {
$class = $this->getReflection()->getMethod('startup')->getDeclaringClass()->getName();
throw new Nette\InvalidStateException("Method $class::startup() or its descendant doesn't call parent::startup().");
}
// calls $this->action()
$this->tryCall($this->formatActionMethod($this->action), $this->params);
// autoload components
foreach ($this->globalParams as $id => $foo) {
$this->getComponent($id, FALSE);
}
if ($this->autoCanonicalize) {
$this->canonicalize();
}
if ($this->httpRequest->isMethod('head')) {
$this->terminate();
}
// SIGNAL HANDLING
// calls $this->handle()
$this->processSignal();
// RENDERING VIEW
$this->beforeRender();
// calls $this->render()
$this->tryCall($this->formatRenderMethod($this->view), $this->params);
$this->afterRender();
// save component tree persistent state
$this->saveGlobalState();
if ($this->isAjax()) {
$this->payload->state = $this->getGlobalState();
}
// finish template rendering
$this->sendTemplate();
} catch (Application\AbortException $e) {
// continue with shutting down
if ($this->isAjax()) try {
$hasPayload = (array) $this->payload; unset($hasPayload['state']);
if ($this->response instanceof Responses\TextResponse && $this->isControlInvalid()) { // snippets - TODO
$this->snippetMode = TRUE;
$this->response->send($this->httpRequest, $this->httpResponse);
$this->sendPayload();
} elseif (!$this->response && $hasPayload) { // back compatibility for use terminate() instead of sendPayload()
$this->sendPayload();
}
} catch (Application\AbortException $e) { }
if ($this->hasFlashSession()) {
$this->getFlashSession()->setExpiration($this->response instanceof Responses\RedirectResponse ? '+ 30 seconds' : '+ 3 seconds');
}
// SHUTDOWN
$this->onShutdown($this, $this->response);
$this->shutdown($this->response);
return $this->response;
}
}
/**
* @return void
*/
protected function startup()
{
$this->startupCheck = TRUE;
}
/**
* Common render method.
* @return void
*/
protected function beforeRender()
{
}
/**
* Common render method.
* @return void
*/
protected function afterRender()
{
}
/**
* @param Nette\Application\IResponse
* @return void
*/
protected function shutdown($response)
{
}
/**
* Checks authorization.
* @return void
*/
public function checkRequirements($element)
{
$user = (array) $element->getAnnotation('User');
if (in_array('loggedIn', $user) && !$this->user->isLoggedIn()) {
throw new Application\ForbiddenRequestException;
}
}
/********************* signal handling ****************d*g**/
/**
* @return void
* @throws BadSignalException
*/
public function processSignal()
{
if ($this->signal === NULL) {
return;
}
try {
$component = $this->signalReceiver === '' ? $this : $this->getComponent($this->signalReceiver, FALSE);
} catch (Nette\InvalidArgumentException $e) {}
if (isset($e) || $component === NULL) {
throw new BadSignalException("The signal receiver component '$this->signalReceiver' is not found.", NULL, isset($e) ? $e : NULL);
} elseif (!$component instanceof ISignalReceiver) {
throw new BadSignalException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor.");
}
$component->signalReceived($this->signal);
$this->signal = NULL;
}
/**
* Returns pair signal receiver and name.
* @return array|NULL
*/
public function getSignal()
{
return $this->signal === NULL ? NULL : array($this->signalReceiver, $this->signal);
}
/**
* Checks if the signal receiver is the given one.
* @param mixed component or its id
* @param string signal name (optional)
* @return bool
*/
public function isSignalReceiver($component, $signal = NULL)
{
if ($component instanceof Nette\ComponentModel\Component) {
$component = $component === $this ? '' : $component->lookupPath(__CLASS__, TRUE);
}
if ($this->signal === NULL) {
return FALSE;
} elseif ($signal === TRUE) {
return $component === ''
|| strncmp($this->signalReceiver . '-', $component . '-', strlen($component) + 1) === 0;
} elseif ($signal === NULL) {
return $this->signalReceiver === $component;
} else {
return $this->signalReceiver === $component && strcasecmp($signal, $this->signal) === 0;
}
}
/********************* rendering ****************d*g**/
/**
* Returns current action name.
* @return string
*/
public function getAction($fullyQualified = FALSE)
{
return $fullyQualified ? ':' . $this->getName() . ':' . $this->action : $this->action;
}
/**
* Changes current action. Only alphanumeric characters are allowed.
* @param string
* @return void
*/
public function changeAction($action)
{
if (is_string($action) && Nette\Utils\Strings::match($action, '#^[a-zA-Z0-9][a-zA-Z0-9_\x7f-\xff]*\z#')) {
$this->action = $action;
$this->view = $action;
} else {
$this->error('Action name is not alphanumeric string.');
}
}
/**
* Returns current view.
* @return string
*/
public function getView()
{
return $this->view;
}
/**
* Changes current view. Any name is allowed.
* @param string
* @return self
*/
public function setView($view)
{
$this->view = (string) $view;
return $this;
}
/**
* Returns current layout name.
* @return string|FALSE
*/
public function getLayout()
{
return $this->layout;
}
/**
* Changes or disables layout.
* @param string|FALSE
* @return self
*/
public function setLayout($layout)
{
$this->layout = $layout === FALSE ? FALSE : (string) $layout;
return $this;
}
/**
* @return void
* @throws Nette\Application\BadRequestException if no template found
* @throws Nette\Application\AbortException
*/
public function sendTemplate()
{
$template = $this->getTemplate();
if (!$template) {
return;
}
if ($template instanceof Nette\Templating\IFileTemplate && !$template->getFile()) { // content template
$files = $this->formatTemplateFiles();
foreach ($files as $file) {
if (is_file($file)) {
$template->setFile($file);
break;
}
}
if (!$template->getFile()) {
$file = preg_replace('#^.*([/\\\\].{1,70})\z#U', "\xE2\x80\xA6\$1", reset($files));
$file = strtr($file, '/', DIRECTORY_SEPARATOR);
$this->error("Page not found. Missing template '$file'.");
}
}
$this->sendResponse(new Responses\TextResponse($template));
}
/**
* Finds layout template file name.
* @return string
*/
public function findLayoutTemplateFile()
{
if ($this->layout === FALSE) {
return;
}
$files = $this->formatLayoutTemplateFiles();
foreach ($files as $file) {
if (is_file($file)) {
return $file;
}
}
if ($this->layout) {
$file = preg_replace('#^.*([/\\\\].{1,70})\z#U', "\xE2\x80\xA6\$1", reset($files));
$file = strtr($file, '/', DIRECTORY_SEPARATOR);
throw new Nette\FileNotFoundException("Layout not found. Missing template '$file'.");
}
}
/**
* Formats layout template file names.
* @return array
*/
public function formatLayoutTemplateFiles()
{
$name = $this->getName();
$presenter = substr($name, strrpos(':' . $name, ':'));
$layout = $this->layout ? $this->layout : 'layout';
$dir = dirname($this->getReflection()->getFileName());
$dir = is_dir("$dir/templates") ? $dir : dirname($dir);
$list = array(
"$dir/templates/$presenter/@$layout.latte",
"$dir/templates/$presenter.@$layout.latte",
"$dir/templates/$presenter/@$layout.phtml",
"$dir/templates/$presenter.@$layout.phtml",
);
do {
$list[] = "$dir/templates/@$layout.latte";
$list[] = "$dir/templates/@$layout.phtml";
$dir = dirname($dir);
} while ($dir && ($name = substr($name, 0, strrpos($name, ':'))));
return $list;
}
/**
* Formats view template file names.
* @return array
*/
public function formatTemplateFiles()
{
$name = $this->getName();
$presenter = substr($name, strrpos(':' . $name, ':'));
$dir = dirname($this->getReflection()->getFileName());
$dir = is_dir("$dir/templates") ? $dir : dirname($dir);
return array(
"$dir/templates/$presenter/$this->view.latte",
"$dir/templates/$presenter.$this->view.latte",
"$dir/templates/$presenter/$this->view.phtml",
"$dir/templates/$presenter.$this->view.phtml",
);
}
/**
* Formats action method name.
* @param string
* @return string
*/
public static function formatActionMethod($action)
{
return 'action' . $action;
}
/**
* Formats render view method name.
* @param string
* @return string
*/
public static function formatRenderMethod($view)
{
return 'render' . $view;
}
/********************* partial AJAX rendering ****************d*g**/
/**
* @return \stdClass
*/
public function getPayload()
{
return $this->payload;
}
/**
* Is AJAX request?
* @return bool
*/
public function isAjax()
{
if ($this->ajaxMode === NULL) {
$this->ajaxMode = $this->httpRequest->isAjax();
}
return $this->ajaxMode;
}
/**
* Sends AJAX payload to the output.
* @return void
* @throws Nette\Application\AbortException
*/
public function sendPayload()
{
$this->sendResponse(new Responses\JsonResponse($this->payload));
}
/**
* Sends JSON data to the output.
* @param mixed $data
* @return void
* @throws Nette\Application\AbortException
*/
public function sendJson($data)
{
$this->sendResponse(new Responses\JsonResponse($data));
}
/********************* navigation & flow ****************d*g**/
/**
* Sends response and terminates presenter.
* @return void
* @throws Nette\Application\AbortException
*/
public function sendResponse(Application\IResponse $response)
{
$this->response = $response;
$this->terminate();
}
/**
* Correctly terminates presenter.
* @return void
* @throws Nette\Application\AbortException
*/
public function terminate()
{
if (func_num_args() !== 0) {
trigger_error(__METHOD__ . ' is not intended to send a Application\Response; use sendResponse() instead.', E_USER_WARNING);
$this->sendResponse(func_get_arg(0));
}
throw new Application\AbortException();
}
/**
* Forward to another presenter or action.
* @param string|Request
* @param array|mixed
* @return void
* @throws Nette\Application\AbortException
*/
public function forward($destination, $args = array())
{
if ($destination instanceof Application\Request) {
$this->sendResponse(new Responses\ForwardResponse($destination));
}
$this->createRequest($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1), 'forward');
$this->sendResponse(new Responses\ForwardResponse($this->lastCreatedRequest));
}
/**
* Redirect to another URL and ends presenter execution.
* @param string
* @param int HTTP error code
* @return void
* @throws Nette\Application\AbortException
*/
public function redirectUrl($url, $code = NULL)
{
if ($this->isAjax()) {
$this->payload->redirect = (string) $url;
$this->sendPayload();
} elseif (!$code) {
$code = $this->httpRequest->isMethod('post')
? Http\IResponse::S303_POST_GET
: Http\IResponse::S302_FOUND;
}
$this->sendResponse(new Responses\RedirectResponse($url, $code));
}
/**
* Throws HTTP error.
* @param string
* @param int HTTP error code
* @return void
* @throws Nette\Application\BadRequestException
*/
public function error($message = NULL, $code = Http\IResponse::S404_NOT_FOUND)
{
throw new Application\BadRequestException($message, $code);
}
/**
* Link to myself.
* @return string
*/
public function backlink()
{
return $this->getAction(TRUE);
}
/**
* Returns the last created Request.
* @return Nette\Application\Request
*/
public function getLastCreatedRequest()
{
return $this->lastCreatedRequest;
}
/**
* Returns the last created Request flag.
* @param string
* @return bool
*/
public function getLastCreatedRequestFlag($flag)
{
return !empty($this->lastCreatedRequestFlag[$flag]);
}
/**
* Conditional redirect to canonicalized URI.
* @return void
* @throws Nette\Application\AbortException
*/
public function canonicalize()
{
if (!$this->isAjax() && ($this->request->isMethod('get') || $this->request->isMethod('head'))) {
try {
$url = $this->createRequest($this, $this->action, $this->getGlobalState() + $this->request->getParameters(), 'redirectX');
} catch (InvalidLinkException $e) {}
if (isset($url) && !$this->httpRequest->getUrl()->isEqual($url)) {
$this->sendResponse(new Responses\RedirectResponse($url, Http\IResponse::S301_MOVED_PERMANENTLY));
}
}
}
/**
* Attempts to cache the sent entity by its last modification date.
* @param string|int|DateTime last modified time
* @param string strong entity tag validator
* @param mixed optional expiration time
* @return void
* @throws Nette\Application\AbortException
*/
public function lastModified($lastModified, $etag = NULL, $expire = NULL)
{
if ($expire !== NULL) {
$this->httpResponse->setExpiration($expire);
}
if (!$this->httpContext->isModified($lastModified, $etag)) {
$this->terminate();
}
}
/**
* Request/URL factory.
* @param PresenterComponent base
* @param string destination in format "[[module:]presenter:]action" or "signal!" or "this"
* @param array array of arguments
* @param string forward|redirect|link
* @return string URL
* @throws InvalidLinkException
* @internal
*/
protected function createRequest($component, $destination, array $args, $mode)
{
// note: createRequest supposes that saveState(), run() & tryCall() behaviour is final
// cached services for better performance
static $presenterFactory, $router, $refUrl;
if ($presenterFactory === NULL) {
$presenterFactory = $this->application->getPresenterFactory();
$router = $this->application->getRouter();
$refUrl = new Http\Url($this->httpRequest->getUrl());
$refUrl->setPath($this->httpRequest->getUrl()->getScriptPath());
}
$this->lastCreatedRequest = $this->lastCreatedRequestFlag = NULL;
// PARSE DESTINATION
// 1) fragment
$a = strpos($destination, '#');
if ($a === FALSE) {
$fragment = '';
} else {
$fragment = substr($destination, $a);
$destination = substr($destination, 0, $a);
}
// 2) ?query syntax
$a = strpos($destination, '?');
if ($a !== FALSE) {
parse_str(substr($destination, $a + 1), $args); // requires disabled magic quotes
$destination = substr($destination, 0, $a);
}
// 3) URL scheme
$a = strpos($destination, '//');
if ($a === FALSE) {
$scheme = FALSE;
} else {
$scheme = substr($destination, 0, $a);
$destination = substr($destination, $a + 2);
}
// 4) signal or empty
if (!$component instanceof Presenter || substr($destination, -1) === '!') {
$signal = rtrim($destination, '!');
$a = strrpos($signal, ':');
if ($a !== FALSE) {
$component = $component->getComponent(strtr(substr($signal, 0, $a), ':', '-'));
$signal = (string) substr($signal, $a + 1);
}
if ($signal == NULL) { // intentionally ==
throw new InvalidLinkException("Signal must be non-empty string.");
}
$destination = 'this';
}
if ($destination == NULL) { // intentionally ==
throw new InvalidLinkException("Destination must be non-empty string.");
}
// 5) presenter: action
$current = FALSE;
$a = strrpos($destination, ':');
if ($a === FALSE) {
$action = $destination === 'this' ? $this->action : $destination;
$presenter = $this->getName();
$presenterClass = get_class($this);
} else {
$action = (string) substr($destination, $a + 1);
if ($destination[0] === ':') { // absolute
if ($a < 2) {
throw new InvalidLinkException("Missing presenter name in '$destination'.");
}
$presenter = substr($destination, 1, $a - 1);
} else { // relative
$presenter = $this->getName();
$b = strrpos($presenter, ':');
if ($b === FALSE) { // no module
$presenter = substr($destination, 0, $a);
} else { // with module
$presenter = substr($presenter, 0, $b + 1) . substr($destination, 0, $a);
}
}
try {
$presenterClass = $presenterFactory->getPresenterClass($presenter);
} catch (Application\InvalidPresenterException $e) {
throw new InvalidLinkException($e->getMessage(), NULL, $e);
}
}
// PROCESS SIGNAL ARGUMENTS
if (isset($signal)) { // $component must be IStatePersistent
$reflection = new PresenterComponentReflection(get_class($component));
if ($signal === 'this') { // means "no signal"
$signal = '';
if (array_key_exists(0, $args)) {
throw new InvalidLinkException("Unable to pass parameters to 'this!' signal.");
}
} elseif (strpos($signal, self::NAME_SEPARATOR) === FALSE) { // TODO: AppForm exception
// counterpart of signalReceived() & tryCall()
$method = $component->formatSignalMethod($signal);
if (!$reflection->hasCallableMethod($method)) {
throw new InvalidLinkException("Unknown signal '$signal', missing handler {$reflection->name}::$method()");
}
if ($args) { // convert indexed parameters to named
self::argsToParams(get_class($component), $method, $args);
}
}
// counterpart of IStatePersistent
if ($args && array_intersect_key($args, $reflection->getPersistentParams())) {
$component->saveState($args);
}
if ($args && $component !== $this) {
$prefix = $component->getUniqueId() . self::NAME_SEPARATOR;
foreach ($args as $key => $val) {
unset($args[$key]);
$args[$prefix . $key] = $val;
}
}
}
// PROCESS ARGUMENTS
if (is_subclass_of($presenterClass, __CLASS__)) {
if ($action === '') {
$action = self::DEFAULT_ACTION;
}
$current = ($action === '*' || strcasecmp($action, $this->action) === 0) && $presenterClass === get_class($this); // TODO
$reflection = new PresenterComponentReflection($presenterClass);
if ($args || $destination === 'this') {
// counterpart of run() & tryCall()
$method = $presenterClass::formatActionMethod($action);
if (!$reflection->hasCallableMethod($method)) {
$method = $presenterClass::formatRenderMethod($action);
if (!$reflection->hasCallableMethod($method)) {
$method = NULL;
}
}
// convert indexed parameters to named
if ($method === NULL) {
if (array_key_exists(0, $args)) {
throw new InvalidLinkException("Unable to pass parameters to action '$presenter:$action', missing corresponding method.");
}
} elseif ($destination === 'this') {
self::argsToParams($presenterClass, $method, $args, $this->params);
} else {
self::argsToParams($presenterClass, $method, $args);
}
}
// counterpart of IStatePersistent
if ($args && array_intersect_key($args, $reflection->getPersistentParams())) {
$this->saveState($args, $reflection);
}
if ($mode === 'redirect') {
$this->saveGlobalState();
}
$globalState = $this->getGlobalState($destination === 'this' ? NULL : $presenterClass);
if ($current && $args) {
$tmp = $globalState + $this->params;
foreach ($args as $key => $val) {
if (http_build_query(array($val)) !== (isset($tmp[$key]) ? http_build_query(array($tmp[$key])) : '')) {
$current = FALSE;
break;
}
}
}
$args += $globalState;
}
// ADD ACTION & SIGNAL & FLASH
if ($action) {
$args[self::ACTION_KEY] = $action;
}
if (!empty($signal)) {
$args[self::SIGNAL_KEY] = $component->getParameterId($signal);
$current = $current && $args[self::SIGNAL_KEY] === $this->getParameter(self::SIGNAL_KEY);
}
if (($mode === 'redirect' || $mode === 'forward') && $this->hasFlashSession()) {
$args[self::FLASH_KEY] = $this->getParameter(self::FLASH_KEY);
}
$this->lastCreatedRequest = new Application\Request(
$presenter,
Application\Request::FORWARD,
$args,
array(),
array()
);
$this->lastCreatedRequestFlag = array('current' => $current);
if ($mode === 'forward' || $mode === 'test') {
return;
}
// CONSTRUCT URL
$url = $router->constructUrl($this->lastCreatedRequest, $refUrl);
if ($url === NULL) {
unset($args[self::ACTION_KEY]);
$params = urldecode(http_build_query($args, NULL, ', '));
throw new InvalidLinkException("No route for $presenter:$action($params)");
}
// make URL relative if possible
if ($mode === 'link' && $scheme === FALSE && !$this->absoluteUrls) {
$hostUrl = $refUrl->getHostUrl() . '/';
if (strncmp($url, $hostUrl, strlen($hostUrl)) === 0) {
$url = substr($url, strlen($hostUrl) - 1);
}
}
return $url . $fragment;
}
/**
* Converts list of arguments to named parameters.
* @param string class name
* @param string method name
* @param array arguments
* @param array supplemental arguments
* @return void
* @throws InvalidLinkException
*/
private static function argsToParams($class, $method, & $args, $supplemental = array())
{
$i = 0;
$rm = new \ReflectionMethod($class, $method);
foreach ($rm->getParameters() as $param) {
$name = $param->getName();
if (array_key_exists($i, $args)) {
$args[$name] = $args[$i];
unset($args[$i]);
$i++;
} elseif (array_key_exists($name, $args)) {
// continue with process
} elseif (array_key_exists($name, $supplemental)) {
$args[$name] = $supplemental[$name];
} else {
continue;
}
if ($args[$name] === NULL) {
continue;
}
$def = $param->isDefaultValueAvailable() && $param->isOptional() ? $param->getDefaultValue() : NULL; // see PHP bug #62988
$type = $param->isArray() ? 'array' : gettype($def);
if (!PresenterComponentReflection::convertType($args[$name], $type)) {
throw new InvalidLinkException("Invalid value for parameter '$name' in method $class::$method(), expected " . ($type === 'NULL' ? 'scalar' : $type) . ".");
}
if ($args[$name] === $def || ($def === NULL && is_scalar($args[$name]) && (string) $args[$name] === '')) {
$args[$name] = NULL; // value transmit is unnecessary
}
}
if (array_key_exists($i, $args)) {
$method = $rm->getName();
throw new InvalidLinkException("Passed more parameters than method $class::$method() expects.");
}
}
/**
* Invalid link handler. Descendant can override this method to change default behaviour.
* @return string
* @throws InvalidLinkException
*/
protected function handleInvalidLink(InvalidLinkException $e)
{
if ($this->invalidLinkMode === self::INVALID_LINK_SILENT) {
return '#';
} elseif ($this->invalidLinkMode === self::INVALID_LINK_WARNING) {
return 'error: ' . $e->getMessage();
} else { // self::INVALID_LINK_EXCEPTION
throw $e;
}
}
/********************* request serialization ****************d*g**/
/**
* Stores current request to session.
* @param mixed optional expiration time
* @return string key
*/
public function storeRequest($expiration = '+ 10 minutes')
{
$session = $this->session->getSection('Nette.Application/requests');
do {
$key = Nette\Utils\Strings::random(5);
} while (isset($session[$key]));
$session[$key] = array($this->user->getId(), $this->request);
$session->setExpiration($expiration, $key);
return $key;
}
/**
* Restores request from session.
* @param string key
* @return void
*/
public function restoreRequest($key)
{
$session = $this->session->getSection('Nette.Application/requests');
if (!isset($session[$key]) || ($session[$key][0] !== NULL && $session[$key][0] !== $this->user->getId())) {
return;
}
$request = clone $session[$key][1];
unset($session[$key]);
$request->setFlag(Application\Request::RESTORED, TRUE);
$params = $request->getParameters();
$params[self::FLASH_KEY] = $this->getParameter(self::FLASH_KEY);
$request->setParameters($params);
$this->sendResponse(new Responses\ForwardResponse($request));
}
/********************* interface IStatePersistent ****************d*g**/
/**
* Returns array of persistent components.
* This default implementation detects components by class-level annotation @persistent(cmp1, cmp2).
* @return array
*/
public static function getPersistentComponents()
{
return (array) Reflection\ClassType::from(get_called_class())->getAnnotation('persistent');
}
/**
* Saves state information for all subcomponents to $this->globalState.
* @return array
*/
private function getGlobalState($forClass = NULL)
{
$sinces = & $this->globalStateSinces;
if ($this->globalState === NULL) {
$state = array();
foreach ($this->globalParams as $id => $params) {
$prefix = $id . self::NAME_SEPARATOR;
foreach ($params as $key => $val) {
$state[$prefix . $key] = $val;
}
}
$this->saveState($state, $forClass ? new PresenterComponentReflection($forClass) : NULL);
if ($sinces === NULL) {
$sinces = array();
foreach ($this->getReflection()->getPersistentParams() as $name => $meta) {
$sinces[$name] = $meta['since'];
}
}
$components = $this->getReflection()->getPersistentComponents();
$iterator = $this->getComponents(TRUE, 'Nette\Application\UI\IStatePersistent');
foreach ($iterator as $name => $component) {
if ($iterator->getDepth() === 0) {
// counts with Nette\Application\RecursiveIteratorIterator::SELF_FIRST
$since = isset($components[$name]['since']) ? $components[$name]['since'] : FALSE; // FALSE = nonpersistent
}
$prefix = $component->getUniqueId() . self::NAME_SEPARATOR;
$params = array();
$component->saveState($params);
foreach ($params as $key => $val) {
$state[$prefix . $key] = $val;
$sinces[$prefix . $key] = $since;
}
}
} else {
$state = $this->globalState;
}
if ($forClass !== NULL) {
$since = NULL;
foreach ($state as $key => $foo) {
if (!isset($sinces[$key])) {
$x = strpos($key, self::NAME_SEPARATOR);
$x = $x === FALSE ? $key : substr($key, 0, $x);
$sinces[$key] = isset($sinces[$x]) ? $sinces[$x] : FALSE;
}
if ($since !== $sinces[$key]) {
$since = $sinces[$key];
$ok = $since && (is_subclass_of($forClass, $since) || $forClass === $since);
}
if (!$ok) {
unset($state[$key]);
}
}
}
return $state;
}
/**
* Permanently saves state information for all subcomponents to $this->globalState.
* @return void
*/
protected function saveGlobalState()
{
$this->globalParams = array();
$this->globalState = $this->getGlobalState();
}
/**
* Initializes $this->globalParams, $this->signal & $this->signalReceiver, $this->action, $this->view. Called by run().
* @return void
* @throws Nette\Application\BadRequestException if action name is not valid
*/
private function initGlobalParameters()
{
// init $this->globalParams
$this->globalParams = array();
$selfParams = array();
$params = $this->request->getParameters();
if ($this->isAjax()) {
$params += $this->request->getPost();
}
foreach ($params as $key => $value) {
if (!preg_match('#^((?:[a-z0-9_]+-)*)((?!\d+\z)[a-z0-9_]+)\z#i', $key, $matches)) {
continue;
} elseif (!$matches[1]) {
$selfParams[$key] = $value;
} else {
$this->globalParams[substr($matches[1], 0, -1)][$matches[2]] = $value;
}
}
// init & validate $this->action & $this->view
$this->changeAction(isset($selfParams[self::ACTION_KEY]) ? $selfParams[self::ACTION_KEY] : self::DEFAULT_ACTION);
// init $this->signalReceiver and key 'signal' in appropriate params array
$this->signalReceiver = $this->getUniqueId();
if (isset($selfParams[self::SIGNAL_KEY])) {
$param = $selfParams[self::SIGNAL_KEY];
if (!is_string($param)) {
$this->error('Signal name is not string.');
}
$pos = strrpos($param, '-');
if ($pos) {
$this->signalReceiver = substr($param, 0, $pos);
$this->signal = substr($param, $pos + 1);
} else {
$this->signalReceiver = $this->getUniqueId();
$this->signal = $param;
}
if ($this->signal == NULL) { // intentionally ==
$this->signal = NULL;
}
}
$this->loadState($selfParams);
}
/**
* Pops parameters for specified component.
* @param string component id
* @return array
*/
public function popGlobalParameters($id)
{
if (isset($this->globalParams[$id])) {
$res = $this->globalParams[$id];
unset($this->globalParams[$id]);
return $res;
} else {
return array();
}
}
/********************* flash session ****************d*g**/
/**
* Checks if a flash session namespace exists.
* @return bool
*/
public function hasFlashSession()
{
return !empty($this->params[self::FLASH_KEY])
&& $this->session->hasSection('Nette.Application.Flash/' . $this->params[self::FLASH_KEY]);
}
/**
* Returns session namespace provided to pass temporary data between redirects.
* @return Nette\Http\SessionSection
*/
public function getFlashSession()
{
if (empty($this->params[self::FLASH_KEY])) {
$this->params[self::FLASH_KEY] = Nette\Utils\Strings::random(4);
}
return $this->session->getSection('Nette.Application.Flash/' . $this->params[self::FLASH_KEY]);
}
/********************* services ****************d*g**/
public function injectPrimary(Nette\DI\Container $context, Application\Application $application, Http\Context $httpContext, Http\IRequest $httpRequest, Http\IResponse $httpResponse, Http\Session $session, Nette\Security\User $user)
{
if ($this->application !== NULL) {
throw new Nette\InvalidStateException("Method " . __METHOD__ . " is intended for initialization and should not be called more than once.");
}
$this->context = $context;
$this->application = $application;
$this->httpContext = $httpContext;
$this->httpRequest = $httpRequest;
$this->httpResponse = $httpResponse;
$this->session = $session;
$this->user = $user;
}
/**
* Gets the context.
* @return \SystemContainer|Nette\DI\Container
* @deprecated
*/
public function getContext()
{
return $this->context;
}
/**
* @deprecated
*/
public function getService($name)
{
trigger_error(__METHOD__ . '() is deprecated; use dependency injection instead.', E_USER_DEPRECATED);
return $this->context->getService($name);
}
/**
* @return Nette\Http\IRequest
*/
protected function getHttpRequest()
{
return $this->httpRequest;
}
/**
* @return Nette\Http\IResponse
*/
protected function getHttpResponse()
{
return $this->httpResponse;
}
/**
* @deprecated
*/
protected function getHttpContext()
{
trigger_error(__METHOD__ . '() is deprecated; use dependency injection instead.', E_USER_DEPRECATED);
return $this->httpContext;
}
/**
* @deprecated
*/
public function getApplication()
{
trigger_error(__METHOD__ . '() is deprecated; use dependency injection instead.', E_USER_DEPRECATED);
return $this->application;
}
/**
* @param string
* @return Nette\Http\Session|Nette\Http\SessionSection
*/
public function getSession($namespace = NULL)
{
$handler = $this->session;
return $namespace === NULL ? $handler : $handler->getSection($namespace);
}
/**
* @return Nette\Security\User
*/
public function getUser()
{
return $this->user;
}
}
Nette-2.1.0/Nette/Application/UI/PresenterComponent.php 100777 0 0 25053 12261522617 16143 0 lookup('Nette\Application\UI\Presenter', $need);
}
/**
* Returns a fully-qualified name that uniquely identifies the component
* within the presenter hierarchy.
* @return string
*/
public function getUniqueId()
{
return $this->lookupPath('Nette\Application\UI\Presenter', TRUE);
}
/**
* This method will be called when the component (or component's parent)
* becomes attached to a monitored object. Do not call this method yourself.
* @param Nette\ComponentModel\IComponent
* @return void
*/
protected function attached($presenter)
{
if ($presenter instanceof Presenter) {
$this->loadState($presenter->popGlobalParameters($this->getUniqueId()));
}
}
/**
* @return void
*/
protected function validateParent(Nette\ComponentModel\IContainer $parent)
{
parent::validateParent($parent);
$this->monitor('Nette\Application\UI\Presenter');
}
/**
* Calls public method if exists.
* @param string
* @param array
* @return bool does method exist?
*/
protected function tryCall($method, array $params)
{
$rc = $this->getReflection();
if ($rc->hasMethod($method)) {
$rm = $rc->getMethod($method);
if ($rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic()) {
$this->checkRequirements($rm);
$rm->invokeArgs($this, $rc->combineArgs($rm, $params));
return TRUE;
}
}
return FALSE;
}
/**
* Checks for requirements such as authorization.
* @return void
*/
public function checkRequirements($element)
{
}
/**
* Access to reflection.
* @return PresenterComponentReflection
*/
public static function getReflection()
{
return new PresenterComponentReflection(get_called_class());
}
/********************* interface IStatePersistent ****************d*g**/
/**
* Loads state informations.
* @param array
* @return void
*/
public function loadState(array $params)
{
$reflection = $this->getReflection();
foreach ($reflection->getPersistentParams() as $name => $meta) {
if (isset($params[$name])) { // NULLs are ignored
$type = gettype($meta['def']);
if (!$reflection->convertType($params[$name], $type)) {
throw new Nette\Application\BadRequestException("Invalid value for persistent parameter '$name' in '{$this->getName()}', expected " . ($type === 'NULL' ? 'scalar' : $type) . ".");
}
$this->$name = & $params[$name];
} else {
$params[$name] = & $this->$name;
}
}
$this->params = $params;
}
/**
* Saves state informations for next request.
* @param array
* @param PresenterComponentReflection (internal, used by Presenter)
* @return void
*/
public function saveState(array & $params, $reflection = NULL)
{
$reflection = $reflection === NULL ? $this->getReflection() : $reflection;
foreach ($reflection->getPersistentParams() as $name => $meta) {
if (isset($params[$name])) {
// injected value
} elseif (array_key_exists($name, $params)) { // NULLs are skipped
continue;
} elseif (!isset($meta['since']) || $this instanceof $meta['since']) {
$params[$name] = $this->$name; // object property value
} else {
continue; // ignored parameter
}
$type = gettype($meta['def']);
if (!PresenterComponentReflection::convertType($params[$name], $type)) {
throw new InvalidLinkException("Invalid value for persistent parameter '$name' in '{$this->getName()}', expected " . ($type === 'NULL' ? 'scalar' : $type) . ".");
}
if ($params[$name] === $meta['def'] || ($meta['def'] === NULL && is_scalar($params[$name]) && (string) $params[$name] === '')) {
$params[$name] = NULL; // value transmit is unnecessary
}
}
}
/**
* Returns component param.
* @param string key
* @param mixed default value
* @return mixed
*/
public function getParameter($name = NULL, $default = NULL)
{
if (func_num_args() === 0) {
trigger_error('Calling ' . __METHOD__ . ' with no arguments to get all parameters is deprecated, use getParameters() instead.', E_USER_DEPRECATED);
return $this->params;
} elseif (isset($this->params[$name])) {
return $this->params[$name];
} else {
return $default;
}
}
/**
* Returns component parameters.
* @return array
*/
public function getParameters()
{
return $this->params;
}
/**
* Returns a fully-qualified name that uniquely identifies the parameter.
* @param string
* @return string
*/
public function getParameterId($name)
{
$uid = $this->getUniqueId();
return $uid === '' ? $name : $uid . self::NAME_SEPARATOR . $name;
}
/** @deprecated */
function getParam($name = NULL, $default = NULL)
{
//trigger_error(__METHOD__ . '() is deprecated; use getParameter() instead.', E_USER_DEPRECATED);
return func_num_args() ? $this->getParameter($name, $default) : $this->getParameter();
}
/**
* Returns array of classes persistent parameters. They have public visibility and are non-static.
* This default implementation detects persistent parameters by annotation @persistent.
* @return array
*/
public static function getPersistentParams()
{
$rc = new Nette\Reflection\ClassType(get_called_class());
$params = array();
foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) {
if (!$rp->isStatic() && $rp->hasAnnotation('persistent')) {
$params[] = $rp->getName();
}
}
return $params;
}
/********************* interface ISignalReceiver ****************d*g**/
/**
* Calls signal handler method.
* @param string
* @return void
* @throws BadSignalException if there is not handler method
*/
public function signalReceived($signal)
{
if (!$this->tryCall($this->formatSignalMethod($signal), $this->params)) {
$class = get_class($this);
throw new BadSignalException("There is no handler for signal '$signal' in class $class.");
}
}
/**
* Formats signal handler method name -> case sensitivity doesn't matter.
* @param string
* @return string
*/
public static function formatSignalMethod($signal)
{
return $signal == NULL ? NULL : 'handle' . $signal; // intentionally ==
}
/********************* navigation ****************d*g**/
/**
* Generates URL to presenter, action or signal.
* @param string destination in format "[[module:]presenter:]action" or "signal!" or "this"
* @param array|mixed
* @return string
* @throws InvalidLinkException
*/
public function link($destination, $args = array())
{
try {
return $this->getPresenter()->createRequest($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1), 'link');
} catch (InvalidLinkException $e) {
return $this->getPresenter()->handleInvalidLink($e);
}
}
/**
* Returns destination as Link object.
* @param string destination in format "[[module:]presenter:]view" or "signal!"
* @param array|mixed
* @return Link
*/
public function lazyLink($destination, $args = array())
{
return new Link($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1));
}
/**
* Determines whether it links to the current page.
* @param string destination in format "[[module:]presenter:]action" or "signal!" or "this"
* @param array|mixed
* @return bool
* @throws InvalidLinkException
*/
public function isLinkCurrent($destination = NULL, $args = array())
{
if ($destination !== NULL) {
$this->getPresenter()->createRequest($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1), 'test');
}
return $this->getPresenter()->getLastCreatedRequestFlag('current');
}
/**
* Redirect to another presenter, action or signal.
* @param int [optional] HTTP error code
* @param string destination in format "[[module:]presenter:]view" or "signal!"
* @param array|mixed
* @return void
* @throws Nette\Application\AbortException
*/
public function redirect($code, $destination = NULL, $args = array())
{
if (!is_numeric($code)) { // first parameter is optional
$args = $destination;
$destination = $code;
$code = NULL;
}
if (!is_array($args)) {
$args = array_slice(func_get_args(), is_numeric($code) ? 2 : 1);
}
$presenter = $this->getPresenter();
$presenter->redirectUrl($presenter->createRequest($this, $destination, $args, 'redirect'), $code);
}
/********************* interface \ArrayAccess ****************d*g**/
/**
* Adds the component to the container.
* @param string component name
* @param Nette\ComponentModel\IComponent
* @return void
*/
public function offsetSet($name, $component)
{
$this->addComponent($component, $name);
}
/**
* Returns component specified by name. Throws exception if component doesn't exist.
* @param string component name
* @return Nette\ComponentModel\IComponent
* @throws Nette\InvalidArgumentException
*/
public function offsetGet($name)
{
return $this->getComponent($name, TRUE);
}
/**
* Does component specified by name exists?
* @param string component name
* @return bool
*/
public function offsetExists($name)
{
return $this->getComponent($name, FALSE) !== NULL;
}
/**
* Removes component from the container.
* @param string component name
* @return void
*/
public function offsetUnset($name)
{
$component = $this->getComponent($name, FALSE);
if ($component !== NULL) {
$this->removeComponent($component);
}
}
}
Nette-2.1.0/Nette/Application/UI/PresenterComponentReflection.php 100777 0 0 10712 12261522617 20152 0 getName() : $class; // TODO
$params = & self::$ppCache[$class];
if ($params !== NULL) {
return $params;
}
$params = array();
if (is_subclass_of($class, 'Nette\Application\UI\PresenterComponent')) {
$defaults = get_class_vars($class);
foreach ($class::getPersistentParams() as $name => $default) {
if (is_int($name)) {
$name = $default;
$default = $defaults[$name];
}
$params[$name] = array(
'def' => $default,
'since' => $class,
);
}
foreach ($this->getPersistentParams(get_parent_class($class)) as $name => $param) {
if (isset($params[$name])) {
$params[$name]['since'] = $param['since'];
continue;
}
$params[$name] = $param;
}
}
return $params;
}
/**
* @param string|NULL
* @return array of persistent components.
*/
public function getPersistentComponents($class = NULL)
{
$class = $class === NULL ? $this->getName() : $class;
$components = & self::$pcCache[$class];
if ($components !== NULL) {
return $components;
}
$components = array();
if (is_subclass_of($class, 'Nette\Application\UI\Presenter')) {
foreach ($class::getPersistentComponents() as $name => $meta) {
if (is_string($meta)) {
$name = $meta;
}
$components[$name] = array('since' => $class);
}
$components = $this->getPersistentComponents(get_parent_class($class)) + $components;
}
return $components;
}
/**
* Is a method callable? It means class is instantiable and method has
* public visibility, is non-static and non-abstract.
* @param string method name
* @return bool
*/
public function hasCallableMethod($method)
{
$class = $this->getName();
$cache = & self::$mcCache[strtolower($class . ':' . $method)];
if ($cache === NULL) try {
$cache = FALSE;
$rm = Nette\Reflection\Method::from($class, $method);
$cache = $this->isInstantiable() && $rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic();
} catch (\ReflectionException $e) {
}
return $cache;
}
/**
* @return array
*/
public static function combineArgs(\ReflectionFunctionAbstract $method, $args)
{
$res = array();
$i = 0;
foreach ($method->getParameters() as $param) {
$name = $param->getName();
if (isset($args[$name])) { // NULLs are ignored
$res[$i++] = $args[$name];
$type = $param->isArray() ? 'array' : ($param->isDefaultValueAvailable() && $param->isOptional() ? gettype($param->getDefaultValue()) : 'NULL');
if (!self::convertType($res[$i-1], $type)) {
$mName = $method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' . $method->getName() : $method->getName();
throw new BadRequestException("Invalid value for parameter '$name' in method $mName(), expected " . ($type === 'NULL' ? 'scalar' : $type) . ".");
}
} else {
$res[$i++] = $param->isDefaultValueAvailable() && $param->isOptional() ? $param->getDefaultValue() : ($param->isArray() ? array() : NULL);
}
}
return $res;
}
/**
* Non data-loss type conversion.
* @param mixed
* @param string
* @return bool
*/
public static function convertType(& $val, $type)
{
if ($val === NULL || is_object($val)) {
// ignore
} elseif ($type === 'array') {
if (!is_array($val)) {
return FALSE;
}
} elseif (!is_scalar($val)) {
return FALSE;
} elseif ($type !== 'NULL') {
$old = $val = ($val === FALSE ? '0' : (string) $val);
settype($val, $type);
if ($old !== ($val === FALSE ? '0' : (string) $val)) {
return FALSE; // data-loss occurs
}
}
return TRUE;
}
}
Nette-2.1.0/Nette/Caching/ 40777 0 0 0 12261522617 10227 5 Nette-2.1.0/Nette/Caching/Cache.php 100777 0 0 21203 12261522617 12061 0 storage = $storage;
$this->namespace = $namespace . self::NAMESPACE_SEPARATOR;
}
/**
* Returns cache storage.
* @return IStorage
*/
public function getStorage()
{
return $this->storage;
}
/**
* Returns cache namespace.
* @return string
*/
public function getNamespace()
{
return (string) substr($this->namespace, 0, -1);
}
/**
* Returns new nested cache object.
* @param string
* @return Cache
*/
public function derive($namespace)
{
$derived = new static($this->storage, $this->namespace . $namespace);
return $derived;
}
/**
* Reads the specified item from the cache or generate it.
* @param mixed key
* @param callable
* @return mixed|NULL
*/
public function load($key, $fallback = NULL)
{
$data = $this->storage->read($this->generateKey($key));
if ($data === NULL && $fallback) {
return $this->save($key, Callback::closure($fallback));
}
return $data;
}
/**
* Writes item into the cache.
* Dependencies are:
* - Cache::PRIORITY => (int) priority
* - Cache::EXPIRATION => (timestamp) expiration
* - Cache::SLIDING => (bool) use sliding expiration?
* - Cache::TAGS => (array) tags
* - Cache::FILES => (array|string) file names
* - Cache::ITEMS => (array|string) cache items
* - Cache::CONSTS => (array|string) cache items
*
* @param mixed key
* @param mixed value
* @param array dependencies
* @return mixed value itself
* @throws Nette\InvalidArgumentException
*/
public function save($key, $data, array $dependencies = NULL)
{
$this->release();
$key = $this->generateKey($key);
if ($data instanceof Nette\Callback || $data instanceof \Closure) {
$this->storage->lock($key);
$data = call_user_func_array($data, array(& $dependencies));
}
if ($data === NULL) {
$this->storage->remove($key);
} else {
$this->storage->write($key, $data, $this->completeDependencies($dependencies, $data));
return $data;
}
}
private function completeDependencies($dp, $data)
{
if (is_object($data)) {
$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data),
Nette\Reflection\ClassType::from($data)->getAnnotation('serializationVersion'));
}
// convert expire into relative amount of seconds
if (isset($dp[Cache::EXPIRATION])) {
$dp[Cache::EXPIRATION] = Nette\DateTime::from($dp[Cache::EXPIRATION])->format('U') - time();
}
// convert FILES into CALLBACKS
if (isset($dp[self::FILES])) {
//clearstatcache();
foreach (array_unique((array) $dp[self::FILES]) as $item) {
$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); // @ - stat may fail
}
unset($dp[self::FILES]);
}
// add namespaces to items
if (isset($dp[self::ITEMS])) {
$dp[self::ITEMS] = array_unique(array_map(array($this, 'generateKey'), (array) $dp[self::ITEMS]));
}
// convert CONSTS into CALLBACKS
if (isset($dp[self::CONSTS])) {
foreach (array_unique((array) $dp[self::CONSTS]) as $item) {
$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item));
}
unset($dp[self::CONSTS]);
}
if (!is_array($dp)) {
$dp = array();
}
return $dp;
}
/**
* Removes item from the cache.
* @param mixed key
* @return void
*/
public function remove($key)
{
$this->save($key, NULL);
}
/**
* Removes items from the cache by conditions.
* Conditions are:
* - Cache::PRIORITY => (int) priority
* - Cache::TAGS => (array) tags
* - Cache::ALL => TRUE
* @return void
*/
public function clean(array $conditions = NULL)
{
$this->release();
$this->storage->clean((array) $conditions);
}
/**
* Caches results of function/method calls.
* @param mixed
* @return mixed
*/
public function call($function)
{
$key = func_get_args();
$key[0] = Callback::toReflection($function);
return $this->load($key, function() use ($function, $key) {
return Callback::invokeArgs($function, array_slice($key, 1));
});
}
/**
* Caches results of function/method calls.
* @param mixed
* @param array dependencies
* @return Closure
*/
public function wrap($function, array $dependencies = NULL)
{
$cache = $this;
return function() use ($cache, $function, $dependencies) {
$key = array(Callback::toReflection($function), func_get_args());
$data = $cache->load($key);
if ($data === NULL) {
$data = $cache->save($key, Callback::invokeArgs($function, $key[1]), $dependencies);
}
return $data;
};
}
/**
* Starts the output cache.
* @param mixed key
* @return OutputHelper|NULL
*/
public function start($key)
{
$data = $this->load($key);
if ($data === NULL) {
return new OutputHelper($this, $key);
}
echo $data;
}
/**
* Generates internal cache key.
*
* @param string
* @return string
*/
protected function generateKey($key)
{
return $this->namespace . md5(is_scalar($key) ? $key : serialize($key));
}
/********************* interface ArrayAccess ****************d*g**/
/**
* Inserts (replaces) item into the cache (\ArrayAccess implementation).
* @param mixed key
* @param mixed
* @return void
* @throws Nette\InvalidArgumentException
*/
public function offsetSet($key, $data)
{
$this->save($key, $data);
}
/**
* Retrieves the specified item from the cache or NULL if the key is not found (\ArrayAccess implementation).
* @param mixed key
* @return mixed|NULL
* @throws Nette\InvalidArgumentException
*/
public function offsetGet($key)
{
$key = is_scalar($key) ? (string) $key : serialize($key);
if ($this->key !== $key) {
$this->key = $key;
$this->data = $this->load($key);
}
return $this->data;
}
/**
* Exists item in cache? (\ArrayAccess implementation).
* @param mixed key
* @return bool
* @throws Nette\InvalidArgumentException
*/
public function offsetExists($key)
{
$this->release();
return $this->offsetGet($key) !== NULL;
}
/**
* Removes the specified item from the cache.
* @param mixed key
* @return void
* @throws Nette\InvalidArgumentException
*/
public function offsetUnset($key)
{
$this->save($key, NULL);
}
/**
* Discards the internal cache used by ArrayAccess.
* @return void
*/
public function release()
{
$this->key = $this->data = NULL;
}
/********************* dependency checkers ****************d*g**/
/**
* Checks CALLBACKS dependencies.
* @param array
* @return bool
*/
public static function checkCallbacks($callbacks)
{
foreach ($callbacks as $callback) {
if (!call_user_func_array(array_shift($callback), $callback)) {
return FALSE;
}
}
return TRUE;
}
/**
* Checks CONSTS dependency.
* @param string
* @param mixed
* @return bool
*/
private static function checkConst($const, $value)
{
return defined($const) && constant($const) === $value;
}
/**
* Checks FILES dependency.
* @param string
* @param int
* @return bool
*/
private static function checkFile($file, $time)
{
return @filemtime($file) == $time; // @ - stat may fail
}
/**
* Checks object @serializationVersion label.
* @param string
* @param mixed
* @return bool
*/
private static function checkSerializationVersion($class, $value)
{
return Nette\Reflection\ClassType::from($class)->getAnnotation('serializationVersion') === $value;
}
}
Nette-2.1.0/Nette/Caching/IStorage.php 100777 0 0 1757 12261522617 12567 0 cache = $cache;
$this->key = $key;
ob_start();
}
/**
* Stops and saves the cache.
* @param array dependencies
* @return void
*/
public function end(array $dependencies = NULL)
{
if ($this->cache === NULL) {
throw new Nette\InvalidStateException('Output cache has already been saved.');
}
$this->cache->save($this->key, ob_get_flush(), (array) $dependencies + (array) $this->dependencies);
$this->cache = NULL;
}
}
Nette-2.1.0/Nette/Caching/Storages/ 40777 0 0 0 12261522617 12016 5 Nette-2.1.0/Nette/Caching/Storages/DevNullStorage.php 100777 0 0 2231 12261522617 15523 0 0,
self::PRIORITY => 1,
self::ENTRIES => 2,
self::DATA => 3,
);
/**
* @param string Directory containing journal file
*/
public function __construct($dir)
{
$this->file = $dir . '/' . self::FILE;
}
/**
* @return void
*/
public function __destruct()
{
if ($this->handle) {
$this->headerCommit();
flock($this->handle, LOCK_UN); // Since PHP 5.3.3 is manual unlock necessary
fclose($this->handle);
$this->handle = FALSE;
}
}
/**
* Writes entry information into the journal.
* @param string
* @param array
* @return void
*/
public function write($key, array $dependencies)
{
$this->lock();
$priority = !isset($dependencies[Cache::PRIORITY]) ? FALSE : (int) $dependencies[Cache::PRIORITY];
$tags = empty($dependencies[Cache::TAGS]) ? FALSE : (array) $dependencies[Cache::TAGS];
$exists = FALSE;
$keyHash = crc32($key);
list($entriesNodeId, $entriesNode) = $this->findIndexNode(self::ENTRIES, $keyHash);
if (isset($entriesNode[$keyHash])) {
$entries = $this->mergeIndexData($entriesNode[$keyHash]);
foreach ($entries as $link => $foo) {
$dataNode = $this->getNode($link >> self::BITROT);
if ($dataNode[$link][self::KEY] === $key) {
if ($dataNode[$link][self::TAGS] == $tags && $dataNode[$link][self::PRIORITY] === $priority) { // intentionally ==, the order of tags does not matter
if ($dataNode[$link][self::DELETED]) {
$dataNode[$link][self::DELETED] = FALSE;
$this->saveNode($link >> self::BITROT, $dataNode);
}
$exists = TRUE;
} else { // Already exists, but with other tags or priority
$toDelete = array();
foreach ($dataNode[$link][self::TAGS] as $tag) {
$toDelete[self::TAGS][$tag][$link] = TRUE;
}
if ($dataNode[$link][self::PRIORITY] !== FALSE) {
$toDelete[self::PRIORITY][$dataNode[$link][self::PRIORITY]][$link] = TRUE;
}
$toDelete[self::ENTRIES][$keyHash][$link] = TRUE;
$this->cleanFromIndex($toDelete);
unset($dataNode[$link]);
$this->saveNode($link >> self::BITROT, $dataNode);
// Node was changed but may be empty, find it again
list($entriesNodeId, $entriesNode) = $this->findIndexNode(self::ENTRIES, $keyHash);
}
break;
}
}
}
if ($exists === FALSE) {
// Magical constants
$requiredSize = strlen($key) + 75;
if ($tags) {
foreach ($tags as $tag) {
$requiredSize += strlen($tag) + 13;
}
}
$requiredSize += $priority ? 10 : 1;
$freeDataNode = $this->findFreeDataNode($requiredSize);
$data = $this->getNode($freeDataNode);
if ($data === FALSE) {
$data = array(
self::INFO => array(
self::LAST_INDEX => ($freeDataNode << self::BITROT),
self::TYPE => self::DATA,
)
);
}
$dataNodeKey = $this->findNextFreeKey($freeDataNode, $data);
$data[$dataNodeKey] = array(
self::KEY => $key,
self::TAGS => $tags ? $tags : array(),
self::PRIORITY => $priority,
self::DELETED => FALSE,
);
$this->saveNode($freeDataNode, $data);
// Save to entries tree, ...
$entriesNode[$keyHash][$dataNodeKey] = 1;
$this->saveNode($entriesNodeId, $entriesNode);
// ...tags tree...
if ($tags) {
foreach ($tags as $tag) {
list($nodeId, $node) = $this->findIndexNode(self::TAGS, $tag);
$node[$tag][$dataNodeKey] = 1;
$this->saveNode($nodeId, $node);
}
}
// ...and priority tree.
if ($priority !== FALSE) {
list($nodeId, $node) = $this->findIndexNode(self::PRIORITY, $priority);
$node[$priority][$dataNodeKey] = 1;
$this->saveNode($nodeId, $node);
}
}
$this->commit();
$this->unlock();
}
/**
* Cleans entries from journal.
* @param array
* @return array of removed items or NULL when performing a full cleanup
*/
public function clean(array $conditions)
{
$this->lock();
if (!empty($conditions[Cache::ALL])) {
$this->nodeCache = $this->nodeChanged = $this->dataNodeFreeSpace = array();
$this->deleteAll();
$this->unlock();
return NULL;
}
$toDelete = array(
self::TAGS => array(),
self::PRIORITY => array(),
self::ENTRIES => array()
);
$entries = array();
if (!empty($conditions[Cache::TAGS])) {
$entries = $this->cleanTags((array) $conditions[Cache::TAGS], $toDelete);
}
if (isset($conditions[Cache::PRIORITY])) {
$this->arrayAppend($entries, $this->cleanPriority((int) $conditions[Cache::PRIORITY], $toDelete));
}
$this->deletedLinks = array();
$this->cleanFromIndex($toDelete);
$this->commit();
$this->unlock();
return $entries;
}
/**
* Cleans entries from journal by tags.
* @param array
* @param array
* @return array of removed items
*/
private function cleanTags(array $tags, array & $toDelete)
{
$entries = array();
foreach ($tags as $tag) {
list(, $node) = $this->findIndexNode(self::TAGS, $tag);
if (isset($node[$tag])) {
$ent = $this->cleanLinks($this->mergeIndexData($node[$tag]), $toDelete);
$this->arrayAppend($entries, $ent);
}
}
return $entries;
}
/**
* Cleans entries from journal by priority.
* @param integer
* @param array
* @return array of removed items
*/
private function cleanPriority($priority, array & $toDelete)
{
list(, $node) = $this->findIndexNode(self::PRIORITY, $priority);
ksort($node);
$allData = array();
foreach ($node as $prior => $data) {
if ($prior === self::INFO) {
continue;
} elseif ($prior > $priority) {
break;
}
$this->arrayAppendKeys($allData, $this->mergeIndexData($data));
}
$nodeInfo = $node[self::INFO];
while ($nodeInfo[self::PREV_NODE] !== -1) {
$nodeId = $nodeInfo[self::PREV_NODE];
$node = $this->getNode($nodeId);
if ($node === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $nodeId.");
}
break;
}
$nodeInfo = $node[self::INFO];
unset($node[self::INFO]);
foreach ($node as $data) {
$this->arrayAppendKeys($allData, $this->mergeIndexData($data));
}
}
return $this->cleanLinks($allData, $toDelete);
}
/**
* Cleans links from $data.
* @param array
* @param array
* @return array of removed items
*/
private function cleanLinks(array $data, array & $toDelete)
{
$return = array();
$data = array_keys($data);
sort($data);
$max = count($data);
$data[] = 0;
$i = 0;
while ($i < $max) {
$searchLink = $data[$i];
if (isset($this->deletedLinks[$searchLink])) {
++$i;
continue;
}
$nodeId = $searchLink >> self::BITROT;
$node = $this->getNode($nodeId);
if ($node === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $nodeId.");
}
++$i;
continue;
}
do {
$link = $data[$i];
if (!isset($node[$link])) {
if (self::$debug) {
throw new Nette\InvalidStateException("Link with ID $searchLink is not in node $nodeId.");
}
continue;
} elseif (isset($this->deletedLinks[$link])) {
continue;
}
$nodeLink = & $node[$link];
if (!$nodeLink[self::DELETED]) {
$nodeLink[self::DELETED] = TRUE;
$return[] = $nodeLink[self::KEY];
} else {
foreach ($nodeLink[self::TAGS] as $tag) {
$toDelete[self::TAGS][$tag][$link] = TRUE;
}
if ($nodeLink[self::PRIORITY] !== FALSE) {
$toDelete[self::PRIORITY][$nodeLink[self::PRIORITY]][$link] = TRUE;
}
$toDelete[self::ENTRIES][crc32($nodeLink[self::KEY])][$link] = TRUE;
unset($node[$link]);
$this->deletedLinks[$link] = TRUE;
}
} while (($data[++$i] >> self::BITROT) === $nodeId);
$this->saveNode($nodeId, $node);
}
return $return;
}
/**
* Remove links to deleted keys from index.
* @param array
*/
private function cleanFromIndex(array $toDeleteFromIndex)
{
foreach ($toDeleteFromIndex as $type => $toDelete) {
ksort($toDelete);
while (!empty($toDelete)) {
reset($toDelete);
$searchKey = key($toDelete);
list($masterNodeId, $masterNode) = $this->findIndexNode($type, $searchKey);
if (!isset($masterNode[$searchKey])) {
if (self::$debug) {
throw new Nette\InvalidStateException('Bad index.');
}
unset($toDelete[$searchKey]);
continue;
}
foreach ($toDelete as $key => $links) {
if (isset($masterNode[$key])) {
foreach ($links as $link => $foo) {
if (isset($masterNode[$key][$link])) {
unset($masterNode[$key][$link], $links[$link]);
}
}
if (!empty($links) && isset($masterNode[$key][self::INDEX_DATA])) {
$this->cleanIndexData($masterNode[$key][self::INDEX_DATA], $links, $masterNode[$key]);
}
if (empty($masterNode[$key])) {
unset($masterNode[$key]);
}
unset($toDelete[$key]);
} else {
break;
}
}
$this->saveNode($masterNodeId, $masterNode);
}
}
}
/**
* Merge data with index data in other nodes.
* @param array
* @return array of merged items
*/
private function mergeIndexData(array $data)
{
while (isset($data[self::INDEX_DATA])) {
$id = $data[self::INDEX_DATA];
unset($data[self::INDEX_DATA]);
$childNode = $this->getNode($id);
if ($childNode === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $id.");
}
break;
}
$this->arrayAppendKeys($data, $childNode[self::INDEX_DATA]);
}
return $data;
}
/**
* Cleans links from other nodes.
* @param int
* @param array
* @param array
* @return void
*/
private function cleanIndexData($nextNodeId, array $links, & $masterNodeLink)
{
$prev = -1;
while ($nextNodeId && !empty($links)) {
$nodeId = $nextNodeId;
$node = $this->getNode($nodeId);
if ($node === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $nodeId.");
}
break;
}
foreach ($links as $link => $foo) {
if (isset($node[self::INDEX_DATA][$link])) {
unset($node[self::INDEX_DATA][$link], $links[$link]);
}
}
if (isset($node[self::INDEX_DATA][self::INDEX_DATA])) {
$nextNodeId = $node[self::INDEX_DATA][self::INDEX_DATA];
} else {
$nextNodeId = FALSE;
}
if (empty($node[self::INDEX_DATA]) || (count($node[self::INDEX_DATA]) === 1 && $nextNodeId)) {
if ($prev === -1) {
if ($nextNodeId === FALSE) {
unset($masterNodeLink[self::INDEX_DATA]);
} else {
$masterNodeLink[self::INDEX_DATA] = $nextNodeId;
}
} else {
$prevNode = $this->getNode($prev);
if ($prevNode === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $prev.");
}
} else {
if ($nextNodeId === FALSE) {
unset($prevNode[self::INDEX_DATA][self::INDEX_DATA]);
if (empty($prevNode[self::INDEX_DATA])) {
unset($prevNode[self::INDEX_DATA]);
}
} else {
$prevNode[self::INDEX_DATA][self::INDEX_DATA] = $nextNodeId;
}
$this->saveNode($prev, $prevNode);
}
}
unset($node[self::INDEX_DATA]);
} else {
$prev = $nodeId;
}
$this->saveNode($nodeId, $node);
}
}
/**
* Get node from journal.
* @param integer
* @return array
*/
private function getNode($id)
{
// Load from cache
if (isset($this->nodeCache[$id])) {
return $this->nodeCache[$id];
}
$binary = stream_get_contents($this->handle, self::NODE_SIZE, self::HEADER_SIZE + self::NODE_SIZE * $id);
if (empty($binary)) {
// empty node, no Exception
return FALSE;
}
list(, $magic, $length) = unpack('N2', $binary);
if ($magic !== self::INDEX_MAGIC && $magic !== self::DATA_MAGIC) {
if (!empty($magic)) {
if (self::$debug) {
throw new Nette\InvalidStateException("Node $id has malformed header.");
}
$this->deleteNode($id);
}
return FALSE;
}
$data = substr($binary, 2 * self::INT32_SIZE, $length - 2 * self::INT32_SIZE);
$node = @unserialize($data); // intentionally @
if ($node === FALSE) {
$this->deleteNode($id);
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot unserialize node number $id.");
}
return FALSE;
}
// Save to cache and return
return $this->nodeCache[$id] = $node;
}
/**
* Save node to cache.
* @param integer
* @param array
* @return void
*/
private function saveNode($id, array $node)
{
if (count($node) === 1) { // Nod contains only INFO
$nodeInfo = $node[self::INFO];
if ($nodeInfo[self::TYPE] !== self::DATA) {
if ($nodeInfo[self::END] !== -1) {
$this->nodeCache[$id] = $node;
$this->nodeChanged[$id] = TRUE;
return;
}
if ($nodeInfo[self::MAX] === -1) {
$max = PHP_INT_MAX;
} else {
$max = $nodeInfo[self::MAX];
}
list(, , $parentId) = $this->findIndexNode($nodeInfo[self::TYPE], $max, $id);
if ($parentId !== -1 && $parentId !== $id) {
$parentNode = $this->getNode($parentId);
if ($parentNode === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $parentId.");
}
} else {
if ($parentNode[self::INFO][self::END] === $id) {
if (count($parentNode) === 1) {
$parentNode[self::INFO][self::END] = -1;
} else {
end($parentNode);
$lastKey = key($parentNode);
$parentNode[self::INFO][self::END] = $parentNode[$lastKey];
unset($parentNode[$lastKey]);
}
} else {
unset($parentNode[$nodeInfo[self::MAX]]);
}
$this->saveNode($parentId, $parentNode);
}
}
if ($nodeInfo[self::TYPE] === self::PRIORITY) { // only priority tree has link to prevNode
if ($nodeInfo[self::MAX] === -1) {
if ($nodeInfo[self::PREV_NODE] !== -1) {
$prevNode = $this->getNode($nodeInfo[self::PREV_NODE]);
if ($prevNode === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number {$nodeInfo[self::PREV_NODE]}.");
}
} else {
$prevNode[self::INFO][self::MAX] = -1;
$this->saveNode($nodeInfo[self::PREV_NODE], $prevNode);
}
}
} else {
list($nextId, $nextNode) = $this->findIndexNode($nodeInfo[self::TYPE], $nodeInfo[self::MAX] + 1, NULL, $id);
if ($nextId !== -1 && $nextId !== $id) {
$nextNode[self::INFO][self::PREV_NODE] = $nodeInfo[self::PREV_NODE];
$this->saveNode($nextId, $nextNode);
}
}
}
}
$this->nodeCache[$id] = FALSE;
} else {
$this->nodeCache[$id] = $node;
}
$this->nodeChanged[$id] = TRUE;
}
/**
* Commit all changed nodes from cache to journal file.
* @return void
*/
private function commit()
{
do {
foreach ($this->nodeChanged as $id => $foo) {
if ($this->prepareNode($id, $this->nodeCache[$id])) {
unset($this->nodeChanged[$id]);
}
}
} while (!empty($this->nodeChanged));
foreach ($this->toCommit as $node => $str) {
$this->commitNode($node, $str);
}
$this->toCommit = array();
}
/**
* Prepare node to journal file structure.
* @param integer
* @param array|bool
* @return bool Successfully committed
*/
private function prepareNode($id, $node)
{
if ($node === FALSE) {
if ($id < $this->lastNode) {
$this->lastNode = $id;
}
unset($this->nodeCache[$id]);
unset($this->dataNodeFreeSpace[$id]);
$this->deleteNode($id);
return TRUE;
}
$data = serialize($node);
$dataSize = strlen($data) + 2 * self::INT32_SIZE;
$isData = $node[self::INFO][self::TYPE] === self::DATA;
if ($dataSize > self::NODE_SIZE) {
if ($isData) {
throw new Nette\InvalidStateException('Saving node is bigger than maximum node size.');
} else {
$this->bisectNode($id, $node);
return FALSE;
}
}
$this->toCommit[$id] = pack('N2', $isData ? self::DATA_MAGIC : self::INDEX_MAGIC, $dataSize) . $data;
if ($this->lastNode < $id) {
$this->lastNode = $id;
}
if ($isData) {
$this->dataNodeFreeSpace[$id] = self::NODE_SIZE - $dataSize;
}
return TRUE;
}
/**
* Commit node string to journal file.
* @param integer
* @param string
* @return void
*/
private function commitNode($id, $str)
{
fseek($this->handle, self::HEADER_SIZE + self::NODE_SIZE * $id);
$written = fwrite($this->handle, $str);
if ($written === FALSE) {
throw new Nette\InvalidStateException("Cannot write node number $id to journal.");
}
}
/**
* Find right node in B+tree. .
* @param string Tree type (TAGS, PRIORITY or ENTRIES)
* @param int Searched item
* @return array Node
*/
private function findIndexNode($type, $search, $childId = NULL, $prevId = NULL)
{
$nodeId = self::$startNode[$type];
$parentId = -1;
while (TRUE) {
$node = $this->getNode($nodeId);
if ($node === FALSE) {
return array(
$nodeId,
array(
self::INFO => array(
self::TYPE => $type,
self::IS_LEAF => TRUE,
self::PREV_NODE => -1,
self::END => -1,
self::MAX => -1,
)
),
$parentId,
); // Init empty node
}
if ($node[self::INFO][self::IS_LEAF] || $nodeId === $childId || $node[self::INFO][self::PREV_NODE] === $prevId) {
return array($nodeId, $node, $parentId);
}
$parentId = $nodeId;
if (isset($node[$search])) {
$nodeId = $node[$search];
} else {
foreach ($node as $key => $childNode) {
if ($key > $search and $key !== self::INFO) {
$nodeId = $childNode;
continue 2;
}
}
$nodeId = $node[self::INFO][self::END];
}
}
}
/**
* Find complete free node.
* @param integer
* @return array|integer Node ID
*/
private function findFreeNode($count = 1)
{
$id = $this->lastNode;
$nodesId = array();
do {
if (isset($this->nodeCache[$id])) {
++$id;
continue;
}
$offset = self::HEADER_SIZE + self::NODE_SIZE * $id;
$binary = stream_get_contents($this->handle, self::INT32_SIZE, $offset);
if (empty($binary)) {
$nodesId[] = $id;
} else {
list(, $magic) = unpack('N', $binary);
if ($magic !== self::INDEX_MAGIC && $magic !== self::DATA_MAGIC) {
$nodesId[] = $id;
}
}
++$id;
} while (count($nodesId) !== $count);
if ($count === 1) {
return $nodesId[0];
} else {
return $nodesId;
}
}
/**
* Find free data node that has $size bytes of free space.
* @param integer size in bytes
* @return integer Node ID
*/
private function findFreeDataNode($size)
{
foreach ($this->dataNodeFreeSpace as $id => $freeSpace) {
if ($freeSpace > $size) {
return $id;
}
}
$id = self::$startNode[self::DATA];
while (TRUE) {
if (isset($this->dataNodeFreeSpace[$id]) || isset($this->nodeCache[$id])) {
++$id;
continue;
}
$offset = self::HEADER_SIZE + self::NODE_SIZE * $id;
$binary = stream_get_contents($this->handle, 2 * self::INT32_SIZE, $offset);
if (empty($binary)) {
$this->dataNodeFreeSpace[$id] = self::NODE_SIZE;
return $id;
}
list(, $magic, $nodeSize) = unpack('N2', $binary);
if (empty($magic)) {
$this->dataNodeFreeSpace[$id] = self::NODE_SIZE;
return $id;
} elseif ($magic === self::DATA_MAGIC) {
$freeSpace = self::NODE_SIZE - $nodeSize;
$this->dataNodeFreeSpace[$id] = $freeSpace;
if ($freeSpace > $size) {
return $id;
}
}
++$id;
}
}
/**
* Bisect node or when has only one key, move part to data node.
* @param integer Node ID
* @param array Node
* @return void
*/
private function bisectNode($id, array $node)
{
$nodeInfo = $node[self::INFO];
unset($node[self::INFO]);
if (count($node) === 1) {
$key = key($node);
$dataId = $this->findFreeDataNode(self::NODE_SIZE);
$this->saveNode($dataId, array(
self::INDEX_DATA => $node[$key],
self::INFO => array(
self::TYPE => self::DATA,
self::LAST_INDEX => ($dataId << self::BITROT),
)));
unset($node[$key]);
$node[$key][self::INDEX_DATA] = $dataId;
$node[self::INFO] = $nodeInfo;
$this->saveNode($id, $node);
return;
}
ksort($node);
$halfCount = ceil(count($node) / 2);
list($first, $second) = array_chunk($node, $halfCount, TRUE);
end($first);
$halfKey = key($first);
if ($id <= 2) { // Root
list($firstId, $secondId) = $this->findFreeNode(2);
$first[self::INFO] = array(
self::TYPE => $nodeInfo[self::TYPE],
self::IS_LEAF => $nodeInfo[self::IS_LEAF],
self::PREV_NODE => -1,
self::END => -1,
self::MAX => $halfKey,
);
$this->saveNode($firstId, $first);
$second[self::INFO] = array(
self::TYPE => $nodeInfo[self::TYPE],
self::IS_LEAF => $nodeInfo[self::IS_LEAF],
self::PREV_NODE => $firstId,
self::END => $nodeInfo[self::END],
self::MAX => -1,
);
$this->saveNode($secondId, $second);
$parentNode = array(
self::INFO => array(
self::TYPE => $nodeInfo[self::TYPE],
self::IS_LEAF => FALSE,
self::PREV_NODE => -1,
self::END => $secondId,
self::MAX => -1,
),
$halfKey => $firstId,
);
$this->saveNode($id, $parentNode);
} else {
$firstId = $this->findFreeNode();
$first[self::INFO] = array(
self::TYPE => $nodeInfo[self::TYPE],
self::IS_LEAF => $nodeInfo[self::IS_LEAF],
self::PREV_NODE => $nodeInfo[self::PREV_NODE],
self::END => -1,
self::MAX => $halfKey,
);
$this->saveNode($firstId, $first);
$second[self::INFO] = array(
self::TYPE => $nodeInfo[self::TYPE],
self::IS_LEAF => $nodeInfo[self::IS_LEAF],
self::PREV_NODE => $firstId,
self::END => $nodeInfo[self::END],
self::MAX => $nodeInfo[self::MAX],
);
$this->saveNode($id, $second);
list(,, $parent) = $this->findIndexNode($nodeInfo[self::TYPE], $halfKey);
$parentNode = $this->getNode($parent);
if ($parentNode === FALSE) {
if (self::$debug) {
throw new Nette\InvalidStateException("Cannot load node number $parent.");
}
} else {
$parentNode[$halfKey] = $firstId;
ksort($parentNode); // Parent index must be always sorted.
$this->saveNode($parent, $parentNode);
}
}
}
/**
* Commit header to journal file.
* @return void
*/
private function headerCommit()
{
fseek($this->handle, self::INT32_SIZE);
@fwrite($this->handle, pack('N', $this->lastNode)); // intentionally @, save is not necessary
}
/**
* Remove node from journal file.
* @param integer
* @return void
*/
private function deleteNode($id)
{
fseek($this->handle, 0, SEEK_END);
$end = ftell($this->handle);
if ($end <= (self::HEADER_SIZE + self::NODE_SIZE * ($id + 1))) {
$packedNull = pack('N', 0);
do {
$binary = stream_get_contents($this->handle, self::INT32_SIZE, (self::HEADER_SIZE + self::NODE_SIZE * --$id));
} while (empty($binary) || $binary === $packedNull);
if (!ftruncate($this->handle, self::HEADER_SIZE + self::NODE_SIZE * ($id + 1))) {
throw new Nette\InvalidStateException('Cannot truncate journal file.');
}
} else {
fseek($this->handle, self::HEADER_SIZE + self::NODE_SIZE * $id);
$written = fwrite($this->handle, pack('N', 0));
if ($written !== self::INT32_SIZE) {
throw new Nette\InvalidStateException("Cannot delete node number $id from journal.");
}
}
}
/**
* Complete delete all nodes from file.
* @throws \Nette\InvalidStateException
*/
private function deleteAll()
{
if (!ftruncate($this->handle, self::HEADER_SIZE)) {
throw new Nette\InvalidStateException('Cannot truncate journal file.');
}
}
/**
* Lock file for writing and reading and delete node cache when file has changed.
* @throws \Nette\InvalidStateException
*/
private function lock()
{
if (!$this->handle) {
$this->prepare();
}
if (!flock($this->handle, LOCK_EX)) {
throw new Nette\InvalidStateException("Cannot acquire exclusive lock on journal file '$this->file'.");
}
$lastProcessIdentifier = stream_get_contents($this->handle, self::INT32_SIZE, self::INT32_SIZE * 2);
if ($lastProcessIdentifier !== $this->processIdentifier) {
$this->nodeCache = $this->dataNodeFreeSpace = array();
// Write current processIdentifier to file header
fseek($this->handle, self::INT32_SIZE * 2);
fwrite($this->handle, $this->processIdentifier);
}
}
/**
* Open btfj.dat file (or create it if not exists) and load metainformation
* @throws \Nette\InvalidStateException
*/
private function prepare()
{
// Create journal file when not exists
if (!file_exists($this->file)) {
$init = @fopen($this->file, 'xb'); // intentionally @
if (!$init) {
clearstatcache();
if (!file_exists($this->file)) {
throw new Nette\InvalidStateException("Cannot create journal file '$this->file'.");
}
} else {
$written = fwrite($init, pack('N2', self::FILE_MAGIC, $this->lastNode));
fclose($init);
if ($written !== self::INT32_SIZE * 2) {
throw new Nette\InvalidStateException("Cannot write journal header.");
}
}
}
$this->handle = fopen($this->file, 'r+b');
if (!$this->handle) {
throw new Nette\InvalidStateException("Cannot open journal file '$this->file'.");
}
if (!flock($this->handle, LOCK_SH)) {
throw new Nette\InvalidStateException('Cannot acquire shared lock on journal.');
}
$header = stream_get_contents($this->handle, 2 * self::INT32_SIZE, 0);
flock($this->handle, LOCK_UN);
list(, $fileMagic, $this->lastNode) = unpack('N2', $header);
if ($fileMagic !== self::FILE_MAGIC) {
fclose($this->handle);
$this->handle = FALSE;
throw new Nette\InvalidStateException("Malformed journal file '$this->file'.");
}
$this->processIdentifier = pack('N', mt_rand());
}
/**
* Unlock file and save last modified time.
* @return void
*/
private function unlock()
{
if ($this->handle) {
fflush($this->handle);
flock($this->handle, LOCK_UN);
}
}
/**
* @param int $nodeId
* @param array $nodeData
* @return int
* @throws \Nette\InvalidStateException
*/
private function findNextFreeKey($nodeId, array & $nodeData)
{
$newKey = $nodeData[self::INFO][self::LAST_INDEX] + 1;
$maxKey = ($nodeId + 1) << self::BITROT;
if ($newKey >= $maxKey) {
$start = $nodeId << self::BITROT;
for ($i = $start; $i < $maxKey; $i++) {
if (!isset($nodeData[$i])) {
return $i;
}
}
throw new Nette\InvalidStateException("Node $nodeId is full.");
} else {
return ++$nodeData[self::INFO][self::LAST_INDEX];
}
}
/**
* Append $append to $array.
* This function is much faster then $array = array_merge($array, $append)
* @param array
* @param array
* @return void
*/
private function arrayAppend(array & $array, array $append)
{
foreach ($append as $value) {
$array[] = $value;
}
}
/**
* Append $append to $array with preserve keys.
* This function is much faster then $array = $array + $append
* @param array
* @param array
* @return void
*/
private function arrayAppendKeys(array & $array, array $append)
{
foreach ($append as $key => $value) {
$array[$key] = $value;
}
}
}
Nette-2.1.0/Nette/Caching/Storages/FileStorage.php 100777 0 0 23236 12261522617 15061 0 timestamp)
META_CALLBACKS = 'callbacks'; // array of callbacks (function, args)
/** additional cache structure */
const FILE = 'file',
HANDLE = 'handle';
/** @var float probability that the clean() routine is started */
public static $gcProbability = 0.001;
/** @var bool */
public static $useDirectories = TRUE;
/** @var string */
private $dir;
/** @var bool */
private $useDirs;
/** @var IJournal */
private $journal;
/** @var array */
private $locks;
public function __construct($dir, IJournal $journal = NULL)
{
$this->dir = realpath($dir);
if ($this->dir === FALSE) {
throw new Nette\DirectoryNotFoundException("Directory '$dir' not found.");
}
$this->useDirs = (bool) static::$useDirectories;
$this->journal = $journal;
if (mt_rand() / mt_getrandmax() < static::$gcProbability) {
$this->clean(array());
}
}
/**
* Read from cache.
* @param string key
* @return mixed|NULL
*/
public function read($key)
{
$meta = $this->readMetaAndLock($this->getCacheFile($key), LOCK_SH);
if ($meta && $this->verify($meta)) {
return $this->readData($meta); // calls fclose()
} else {
return NULL;
}
}
/**
* Verifies dependencies.
* @param array
* @return bool
*/
private function verify($meta)
{
do {
if (!empty($meta[self::META_DELTA])) {
// meta[file] was added by readMetaAndLock()
if (filemtime($meta[self::FILE]) + $meta[self::META_DELTA] < time()) {
break;
}
touch($meta[self::FILE]);
} elseif (!empty($meta[self::META_EXPIRE]) && $meta[self::META_EXPIRE] < time()) {
break;
}
if (!empty($meta[self::META_CALLBACKS]) && !Cache::checkCallbacks($meta[self::META_CALLBACKS])) {
break;
}
if (!empty($meta[self::META_ITEMS])) {
foreach ($meta[self::META_ITEMS] as $depFile => $time) {
$m = $this->readMetaAndLock($depFile, LOCK_SH);
if ($m[self::META_TIME] !== $time || ($m && !$this->verify($m))) {
break 2;
}
}
}
return TRUE;
} while (FALSE);
$this->delete($meta[self::FILE], $meta[self::HANDLE]); // meta[handle] & meta[file] was added by readMetaAndLock()
return FALSE;
}
/**
* Prevents item reading and writing. Lock is released by write() or remove().
* @param string key
* @return void
*/
public function lock($key)
{
$cacheFile = $this->getCacheFile($key);
if ($this->useDirs && !is_dir($dir = dirname($cacheFile))) {
@mkdir($dir); // @ - directory may already exist
}
$handle = @fopen($cacheFile, 'r+b'); // @ - file may not exist
if (!$handle) {
$handle = fopen($cacheFile, 'wb');
if (!$handle) {
return;
}
}
$this->locks[$key] = $handle;
flock($handle, LOCK_EX);
}
/**
* Writes item into the cache.
* @param string key
* @param mixed data
* @param array dependencies
* @return void
*/
public function write($key, $data, array $dp)
{
$meta = array(
self::META_TIME => microtime(),
);
if (isset($dp[Cache::EXPIRATION])) {
if (empty($dp[Cache::SLIDING])) {
$meta[self::META_EXPIRE] = $dp[Cache::EXPIRATION] + time(); // absolute time
} else {
$meta[self::META_DELTA] = (int) $dp[Cache::EXPIRATION]; // sliding time
}
}
if (isset($dp[Cache::ITEMS])) {
foreach ((array) $dp[Cache::ITEMS] as $item) {
$depFile = $this->getCacheFile($item);
$m = $this->readMetaAndLock($depFile, LOCK_SH);
$meta[self::META_ITEMS][$depFile] = $m[self::META_TIME]; // may be NULL
unset($m);
}
}
if (isset($dp[Cache::CALLBACKS])) {
$meta[self::META_CALLBACKS] = $dp[Cache::CALLBACKS];
}
if (!isset($this->locks[$key])) {
$this->lock($key);
if (!isset($this->locks[$key])) {
return;
}
}
$handle = $this->locks[$key];
unset($this->locks[$key]);
$cacheFile = $this->getCacheFile($key);
if (isset($dp[Cache::TAGS]) || isset($dp[Cache::PRIORITY])) {
if (!$this->journal) {
throw new Nette\InvalidStateException('CacheJournal has not been provided.');
}
$this->journal->write($cacheFile, $dp);
}
ftruncate($handle, 0);
if (!is_string($data)) {
$data = serialize($data);
$meta[self::META_SERIALIZED] = TRUE;
}
$head = serialize($meta) . '?>';
$head = 'delete($cacheFile, $handle);
}
/**
* Removes item from the cache.
* @param string key
* @return void
*/
public function remove($key)
{
unset($this->locks[$key]);
$this->delete($this->getCacheFile($key));
}
/**
* Removes items from the cache by conditions & garbage collector.
* @param array conditions
* @return void
*/
public function clean(array $conditions)
{
$all = !empty($conditions[Cache::ALL]);
$collector = empty($conditions);
// cleaning using file iterator
if ($all || $collector) {
$now = time();
foreach (Nette\Utils\Finder::find('_*')->from($this->dir)->childFirst() as $entry) {
$path = (string) $entry;
if ($entry->isDir()) { // collector: remove empty dirs
@rmdir($path); // @ - removing dirs is not necessary
continue;
}
if ($all) {
$this->delete($path);
} else { // collector
$meta = $this->readMetaAndLock($path, LOCK_SH);
if (!$meta) {
continue;
}
if ((!empty($meta[self::META_DELTA]) && filemtime($meta[self::FILE]) + $meta[self::META_DELTA] < $now)
|| (!empty($meta[self::META_EXPIRE]) && $meta[self::META_EXPIRE] < $now)
) {
$this->delete($path, $meta[self::HANDLE]);
continue;
}
flock($meta[self::HANDLE], LOCK_UN);
fclose($meta[self::HANDLE]);
}
}
if ($this->journal) {
$this->journal->clean($conditions);
}
return;
}
// cleaning using journal
if ($this->journal) {
foreach ($this->journal->clean($conditions) as $file) {
$this->delete($file);
}
}
}
/**
* Reads cache data from disk.
* @param string file path
* @param int lock mode
* @return array|NULL
*/
protected function readMetaAndLock($file, $lock)
{
$handle = @fopen($file, 'r+b'); // @ - file may not exist
if (!$handle) {
return NULL;
}
flock($handle, $lock);
$head = stream_get_contents($handle, self::META_HEADER_LEN);
if ($head && strlen($head) === self::META_HEADER_LEN) {
$size = (int) substr($head, -6);
$meta = stream_get_contents($handle, $size, self::META_HEADER_LEN);
$meta = @unserialize($meta); // intentionally @
if (is_array($meta)) {
$meta[self::FILE] = $file;
$meta[self::HANDLE] = $handle;
return $meta;
}
}
flock($handle, LOCK_UN);
fclose($handle);
return NULL;
}
/**
* Reads cache data from disk and closes cache file handle.
* @param array
* @return mixed
*/
protected function readData($meta)
{
$data = stream_get_contents($meta[self::HANDLE]);
flock($meta[self::HANDLE], LOCK_UN);
fclose($meta[self::HANDLE]);
if (empty($meta[self::META_SERIALIZED])) {
return $data;
} else {
return @unserialize($data); // intentionally @
}
}
/**
* Returns file name.
* @param string
* @return string
*/
protected function getCacheFile($key)
{
$file = urlencode($key);
if ($this->useDirs && $a = strrpos($file, '%00')) { // %00 = urlencode(Nette\Caching\Cache::NAMESPACE_SEPARATOR)
$file = substr_replace($file, '/_', $a, 3);
}
return $this->dir . '/_' . $file;
}
/**
* Deletes and closes file.
* @param string
* @param resource
* @return void
*/
private static function delete($file, $handle = NULL)
{
if (@unlink($file)) { // @ - file may not already exist
if ($handle) {
flock($handle, LOCK_UN);
fclose($handle);
}
return;
}
if (!$handle) {
$handle = @fopen($file, 'r+'); // @ - file may not exist
}
if ($handle) {
flock($handle, LOCK_EX);
ftruncate($handle, 0);
flock($handle, LOCK_UN);
fclose($handle);
@unlink($file); // @ - file may not already exist
}
}
}
Nette-2.1.0/Nette/Caching/Storages/IJournal.php 100777 0 0 1240 12261522617 14347 0 prefix = $prefix;
$this->journal = $journal;
$this->memcache = new \Memcache;
if ($host) {
$this->addServer($host, $port);
}
}
public function addServer($host = 'localhost', $port = 11211, $timeout = 1)
{
if ($this->memcache->addServer($host, $port, TRUE, 1, $timeout) === FALSE) {
$error = error_get_last();
throw new Nette\InvalidStateException("Memcache::addServer(): $error[message].");
}
}
/**
* @return \Memcache
*/
public function getConnection()
{
return $this->memcache;
}
/**
* Read from cache.
* @param string key
* @return mixed|NULL
*/
public function read($key)
{
$key = $this->prefix . $key;
$meta = $this->memcache->get($key);
if (!$meta) {
return NULL;
}
// meta structure:
// array(
// data => stored data
// delta => relative (sliding) expiration
// callbacks => array of callbacks (function, args)
// )
// verify dependencies
if (!empty($meta[self::META_CALLBACKS]) && !Cache::checkCallbacks($meta[self::META_CALLBACKS])) {
$this->memcache->delete($key, 0);
return NULL;
}
if (!empty($meta[self::META_DELTA])) {
$this->memcache->replace($key, $meta, 0, $meta[self::META_DELTA] + time());
}
return $meta[self::META_DATA];
}
/**
* Prevents item reading and writing. Lock is released by write() or remove().
* @param string key
* @return void
*/
public function lock($key)
{
}
/**
* Writes item into the cache.
* @param string key
* @param mixed data
* @param array dependencies
* @return void
*/
public function write($key, $data, array $dp)
{
if (isset($dp[Cache::ITEMS])) {
throw new Nette\NotSupportedException('Dependent items are not supported by MemcachedStorage.');
}
$key = $this->prefix . $key;
$meta = array(
self::META_DATA => $data,
);
$expire = 0;
if (isset($dp[Cache::EXPIRATION])) {
$expire = (int) $dp[Cache::EXPIRATION];
if (!empty($dp[Cache::SLIDING])) {
$meta[self::META_DELTA] = $expire; // sliding time
}
}
if (isset($dp[Cache::CALLBACKS])) {
$meta[self::META_CALLBACKS] = $dp[Cache::CALLBACKS];
}
if (isset($dp[Cache::TAGS]) || isset($dp[Cache::PRIORITY])) {
if (!$this->journal) {
throw new Nette\InvalidStateException('CacheJournal has not been provided.');
}
$this->journal->write($key, $dp);
}
$this->memcache->set($key, $meta, 0, $expire);
}
/**
* Removes item from the cache.
* @param string key
* @return void
*/
public function remove($key)
{
$this->memcache->delete($this->prefix . $key, 0);
}
/**
* Removes items from the cache by conditions & garbage collector.
* @param array conditions
* @return void
*/
public function clean(array $conditions)
{
if (!empty($conditions[Cache::ALL])) {
$this->memcache->flush();
} elseif ($this->journal) {
foreach ($this->journal->clean($conditions) as $entry) {
$this->memcache->delete($entry, 0);
}
}
}
}
Nette-2.1.0/Nette/Caching/Storages/MemoryStorage.php 100777 0 0 2634 12261522617 15431 0 data[$key]) ? $this->data[$key] : NULL;
}
/**
* Prevents item reading and writing. Lock is released by write() or remove().
* @param string key
* @return void
*/
public function lock($key)
{
}
/**
* Writes item into the cache.
* @param string key
* @param mixed data
* @param array dependencies
* @return void
*/
public function write($key, $data, array $dependencies)
{
$this->data[$key] = $data;
}
/**
* Removes item from the cache.
* @param string key
* @return void
*/
public function remove($key)
{
unset($this->data[$key]);
}
/**
* Removes items from the cache by conditions & garbage collector.
* @param array conditions
* @return void
*/
public function clean(array $conditions)
{
if (!empty($conditions[Nette\Caching\Cache::ALL])) {
$this->data = array();
}
}
}
Nette-2.1.0/Nette/Caching/Storages/PhpFileStorage.php 100777 0 0 1613 12261522617 15504 0 $meta[self::FILE],
'handle' => $meta[self::HANDLE],
);
}
/**
* Returns file name.
* @param string
* @return string
*/
protected function getCacheFile($key)
{
return parent::getCacheFile(substr_replace(
$key,
trim(strtr($this->hint, '\\/@', '.._'), '.') . '-',
strpos($key, Nette\Caching\Cache::NAMESPACE_SEPARATOR) + 1,
0
)) . '.php';
}
}
Nette-2.1.0/Nette/Caching/Storages/SQLiteStorage.php 100777 0 0 5624 12261522617 15324 0 pdo = new \PDO('sqlite:' . $path, NULL, NULL, array(\PDO::ATTR_PERSISTENT => TRUE));
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->pdo->exec('
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS cache (
key BLOB NOT NULL PRIMARY KEY, data BLOB NOT NULL
);
CREATE TABLE IF NOT EXISTS tags (
key BLOB NOT NULL REFERENCES cache ON DELETE CASCADE,
tag BLOB NOT NULL
);
CREATE INDEX IF NOT EXISTS tags_key ON tags(key);
CREATE INDEX IF NOT EXISTS tags_tag ON tags(tag);
');
}
/**
* Read from cache.
* @param string key
* @return mixed|NULL
*/
public function read($key)
{
$stmt = $this->pdo->prepare('SELECT data FROM cache WHERE key=?');
$stmt->execute(array($key));
if ($res = $stmt->fetchColumn()) {
return unserialize($res);
}
}
/**
* Prevents item reading and writing. Lock is released by write() or remove().
* @param string key
* @return void
*/
public function lock($key)
{
}
/**
* Writes item into the cache.
* @param string key
* @param mixed data
* @param array dependencies
* @return void
*/
public function write($key, $data, array $dependencies)
{
$this->pdo->prepare('BEGIN TRANSACTION');
$this->pdo->prepare('REPLACE INTO cache (key, data) VALUES (?, ?)')
->execute(array($key, serialize($data)));
if (!empty($dependencies[Cache::TAGS])) {
foreach ((array) $dependencies[Cache::TAGS] as $tag) {
$arr[] = $key;
$arr[] = $tag;
}
$this->pdo->prepare('INSERT INTO tags (key, tag) SELECT ?, ?' . str_repeat('UNION SELECT ?, ?', count($arr) / 2 - 1))
->execute($arr);
}
$this->pdo->prepare('COMMIT');
}
/**
* Removes item from the cache.
* @param string key
* @return void
*/
public function remove($key)
{
$this->pdo->prepare('DELETE FROM cache WHERE key=?')
->execute(array($key));
}
/**
* Removes items from the cache by conditions & garbage collector.
* @param array conditions
* @return void
*/
public function clean(array $conditions)
{
if (!empty($conditions[Cache::ALL])) {
$this->pdo->prepare('DELETE FROM cache');
} elseif (!empty($conditions[Cache::TAGS])) {
$tags = (array) $conditions[Cache::TAGS];
$this->pdo->prepare('DELETE FROM cache WHERE key IN (SELECT key FROM tags WHERE tag IN (?'
. str_repeat(',?', count($tags) - 1) . '))')->execute($tags);
}
}
}
Nette-2.1.0/Nette/common/ 40777 0 0 0 12261522617 10163 5 Nette-2.1.0/Nette/common/ArrayHash.php 100777 0 0 3314 12261522617 12657 0 $value) {
if ($recursive && is_array($value)) {
$obj->$key = static::from($value, TRUE);
} else {
$obj->$key = $value;
}
}
return $obj;
}
/**
* Returns an iterator over all items.
* @return \RecursiveArrayIterator
*/
public function getIterator()
{
return new \RecursiveArrayIterator($this);
}
/**
* Returns items count.
* @return int
*/
public function count()
{
return count((array) $this);
}
/**
* Replaces or appends a item.
* @return void
*/
public function offsetSet($key, $value)
{
if (!is_scalar($key)) { // prevents NULL
throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
}
$this->$key = $value;
}
/**
* Returns a item.
* @return mixed
*/
public function offsetGet($key)
{
return $this->$key;
}
/**
* Determines whether a item exists.
* @return bool
*/
public function offsetExists($key)
{
return isset($this->$key);
}
/**
* Removes the element from this list.
* @return void
*/
public function offsetUnset($key)
{
unset($this->$key);
}
}
Nette-2.1.0/Nette/common/ArrayList.php 100777 0 0 4026 12261522617 12710 0 list);
}
/**
* Returns items count.
* @return int
*/
public function count()
{
return count($this->list);
}
/**
* Replaces or appends a item.
* @param int
* @param mixed
* @return void
* @throws OutOfRangeException
*/
public function offsetSet($index, $value)
{
if ($index === NULL) {
$this->list[] = $value;
} elseif ($index < 0 || $index >= count($this->list)) {
throw new OutOfRangeException("Offset invalid or out of range");
} else {
$this->list[(int) $index] = $value;
}
}
/**
* Returns a item.
* @param int
* @return mixed
* @throws OutOfRangeException
*/
public function offsetGet($index)
{
if ($index < 0 || $index >= count($this->list)) {
throw new OutOfRangeException("Offset invalid or out of range");
}
return $this->list[(int) $index];
}
/**
* Determines whether a item exists.
* @param int
* @return bool
*/
public function offsetExists($index)
{
return $index >= 0 && $index < count($this->list);
}
/**
* Removes the element at the specified position in this list.
* @param int
* @return void
* @throws OutOfRangeException
*/
public function offsetUnset($index)
{
if ($index < 0 || $index >= count($this->list)) {
throw new OutOfRangeException("Offset invalid or out of range");
}
array_splice($this->list, (int) $index, 1);
}
}
Nette-2.1.0/Nette/common/Callback.php 100777 0 0 7025 12261522617 12474 0 invoke() in PHP 5.3.
* @param mixed class, object, callable
* @param string method
* @return Callback
*/
public static function create($callback, $m = NULL)
{
return new self($callback, $m);
}
/**
* @param mixed class, object, callable
* @param string method
*/
public function __construct($cb, $m = NULL)
{
if ($m !== NULL) {
$cb = array($cb, $m);
} elseif ($cb instanceof self) { // prevents wrapping itself
$this->cb = $cb->cb;
return;
}
if (!is_callable($cb, TRUE)) {
throw new InvalidArgumentException("Invalid callback.");
}
$this->cb = $cb;
}
/**
* Invokes callback. Do not call directly.
* @return mixed
*/
public function __invoke()
{
if (!is_callable($this->cb)) {
throw new InvalidStateException("Callback '$this' is not callable.");
}
return call_user_func_array($this->cb, func_get_args());
}
/**
* Invokes callback.
* @return mixed
*/
public function invoke()
{
if (!is_callable($this->cb)) {
throw new InvalidStateException("Callback '$this' is not callable.");
}
return call_user_func_array($this->cb, func_get_args());
}
/**
* Invokes callback with an array of parameters.
* @param array
* @return mixed
*/
public function invokeArgs(array $args)
{
if (!is_callable($this->cb)) {
throw new InvalidStateException("Callback '$this' is not callable.");
}
return call_user_func_array($this->cb, $args);
}
/**
* Verifies that callback can be called.
* @return bool
*/
public function isCallable()
{
return is_callable($this->cb);
}
/**
* Returns PHP callback pseudotype.
* @return string|array|\Closure
*/
public function getNative()
{
return $this->cb;
}
/**
* Returns callback reflection.
* @return Nette\Reflection\GlobalFunction|Nette\Reflection\Method
*/
public function toReflection()
{
if (is_string($this->cb) && strpos($this->cb, '::')) {
return new Nette\Reflection\Method($this->cb);
} elseif (is_array($this->cb)) {
return new Nette\Reflection\Method($this->cb[0], $this->cb[1]);
} elseif (is_object($this->cb) && !$this->cb instanceof \Closure) {
return new Nette\Reflection\Method($this->cb, '__invoke');
} else {
return new Nette\Reflection\GlobalFunction($this->cb);
}
}
/**
* @return bool
*/
public function isStatic()
{
return is_array($this->cb) ? is_string($this->cb[0]) : is_string($this->cb);
}
/**
* Duplicates the callback with a new bound object.
* @return Callback
*/
public function bindTo($newthis)
{
if (is_string($this->cb) && strpos($this->cb, '::')) {
$this->cb = explode('::', $this->cb);
} elseif (!is_array($this->cb)) {
throw new InvalidStateException("Callback '$this' have not any bound object.");
}
return new static($newthis, $this->cb[1]);
}
/**
* @return string
*/
public function __toString()
{
if ($this->cb instanceof \Closure) {
return '{closure}';
} elseif (is_string($this->cb) && $this->cb[0] === "\0") {
return '{lambda}';
} else {
is_callable($this->cb, TRUE, $textual);
return $textual;
}
}
}
Nette-2.1.0/Nette/common/Configurator.php 100777 0 0 17024 12261522617 13462 0 'Nette\DI\Extensions\PhpExtension',
'constants' => 'Nette\DI\Extensions\ConstantsExtension',
'nette' => 'Nette\DI\Extensions\NetteExtension',
'extensions' => 'Nette\DI\Extensions\ExtensionsExtension',
);
/** @var array */
protected $parameters;
/** @var array */
protected $files = array();
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
}
/**
* Set parameter %debugMode%.
* @param bool|string|array
* @return self
*/
public function setDebugMode($value = TRUE)
{
$this->parameters['debugMode'] = is_string($value) || is_array($value) ? static::detectDebugMode($value) : (bool) $value;
$this->parameters['productionMode'] = !$this->parameters['debugMode']; // compatibility
return $this;
}
/**
* @return bool
*/
public function isDebugMode()
{
return $this->parameters['debugMode'];
}
/**
* Sets path to temporary directory.
* @return self
*/
public function setTempDirectory($path)
{
$this->parameters['tempDir'] = $path;
return $this;
}
/**
* Adds new parameters. The %params% will be expanded.
* @return self
*/
public function addParameters(array $params)
{
$this->parameters = DI\Config\Helpers::merge($params, $this->parameters);
return $this;
}
/**
* @return array
*/
protected function getDefaultParameters()
{
$trace = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE);
$debugMode = static::detectDebugMode();
return array(
'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL,
'wwwDir' => isset($_SERVER['SCRIPT_FILENAME'])
? dirname(realpath($_SERVER['SCRIPT_FILENAME']))
: NULL,
'debugMode' => $debugMode,
'productionMode' => !$debugMode,
'environment' => $debugMode ? 'development' : 'production',
'consoleMode' => PHP_SAPI === 'cli',
'container' => array(
'class' => 'SystemContainer',
'parent' => 'Nette\DI\Container',
)
);
}
/**
* @param string error log directory
* @param string administrator email
* @return void
*/
public function enableDebugger($logDirectory = NULL, $email = NULL)
{
Nette\Diagnostics\Debugger::$strictMode = TRUE;
Nette\Diagnostics\Debugger::enable(!$this->parameters['debugMode'], $logDirectory, $email);
}
/**
* @return Nette\Loaders\RobotLoader
*/
public function createRobotLoader()
{
$loader = new Nette\Loaders\RobotLoader;
$loader->setCacheStorage(new Nette\Caching\Storages\FileStorage($this->getCacheDirectory()));
$loader->autoRebuild = $this->parameters['debugMode'];
return $loader;
}
/**
* Adds configuration file.
* @return self
*/
public function addConfig($file, $section = NULL)
{
$this->files[] = array($file, $section === self::AUTO ? $this->parameters['environment'] : $section);
return $this;
}
/**
* Returns system DI container.
* @return \SystemContainer
*/
public function createContainer()
{
$cache = new Nette\Caching\Cache(new Nette\Caching\Storages\PhpFileStorage($this->getCacheDirectory()), 'Nette.Configurator');
$cacheKey = array($this->parameters, $this->files);
$cached = $cache->load($cacheKey);
if (!$cached) {
$code = $this->buildContainer($dependencies);
$cache->save($cacheKey, $code, array($cache::FILES => $dependencies));
$cached = $cache->load($cacheKey);
}
require_once $cached['file'];
$container = new $this->parameters['container']['class'];
$container->initialize();
Nette\Environment::setContext($container); // back compatibility
return $container;
}
/**
* Build system container class.
* @return string
*/
protected function buildContainer(& $dependencies = NULL)
{
$loader = $this->createLoader();
$config = array();
$code = "files as $tmp) {
list($file, $section) = $tmp;
$code .= "// source: $file $section\n";
try {
if ($section === NULL) { // back compatibility
$config = DI\Config\Helpers::merge($loader->load($file, $this->parameters['environment']), $config);
continue;
}
} catch (Nette\InvalidStateException $e) {
} catch (Nette\Utils\AssertionException $e) {
}
$config = DI\Config\Helpers::merge($loader->load($file, $section), $config);
}
$code .= "\n";
if (!isset($config['parameters'])) {
$config['parameters'] = array();
}
$config['parameters'] = DI\Config\Helpers::merge($config['parameters'], $this->parameters);
$compiler = $this->createCompiler();
$this->onCompile($this, $compiler);
$code .= $compiler->compile(
$config,
$this->parameters['container']['class'],
$config['parameters']['container']['parent']
);
$dependencies = array_merge($loader->getDependencies(), $this->parameters['debugMode'] ? $compiler->getContainerBuilder()->getDependencies() : array());
return $code;
}
/**
* @return Compiler
*/
protected function createCompiler()
{
$compiler = new DI\Compiler;
foreach ($this->defaultExtensions as $name => $class) {
$compiler->addExtension($name, new $class);
}
return $compiler;
}
/**
* @return Loader
*/
protected function createLoader()
{
return new DI\Config\Loader;
}
protected function getCacheDirectory()
{
if (empty($this->parameters['tempDir'])) {
throw new Nette\InvalidStateException("Set path to temporary directory using setTempDirectory().");
}
$dir = $this->parameters['tempDir'] . '/cache';
if (!is_dir($dir)) {
mkdir($dir);
}
return $dir;
}
/********************* tools ****************d*g**/
/**
* Detects debug mode by IP address.
* @param string|array IP addresses or computer names whitelist detection
* @return bool
*/
public static function detectDebugMode($list = NULL)
{
$list = is_string($list) ? preg_split('#[,\s]+#', $list) : (array) $list;
if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$list[] = '127.0.0.1';
$list[] = '::1';
}
return in_array(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : php_uname('n'), $list, TRUE);
}
/** @deprecated */
public function setProductionMode($value = TRUE)
{
trigger_error(__METHOD__ . '() is deprecated; use setDebugMode(!$value) instead.', E_USER_DEPRECATED);
return $this->setDebugMode(is_bool($value) ? !$value : $value);
}
/** @deprecated */
public function isProductionMode()
{
trigger_error(__METHOD__ . '() is deprecated; use !isDebugMode() instead.', E_USER_DEPRECATED);
return !$this->isDebugMode();
}
/** @deprecated */
public static function detectProductionMode($list = NULL)
{
trigger_error(__METHOD__ . '() is deprecated; use !detectDebugMode() instead.', E_USER_DEPRECATED);
return !static::detectDebugMode($list);
}
}
Nette-2.1.0/Nette/common/DateTime.php 100777 0 0 3212 12261522617 12466 0 format('Y-m-d H:i:s'), $time->getTimezone());
} elseif (is_numeric($time)) {
if ($time <= self::YEAR) {
$time += time();
}
$tmp = new static('@' . $time);
return $tmp->setTimeZone(new \DateTimeZone(date_default_timezone_get()));
} else { // textual or NULL
return new static($time);
}
}
public function __toString()
{
return $this->format('Y-m-d H:i:s');
}
public function modifyClone($modify = '')
{
$dolly = clone $this;
return $modify ? $dolly->modify($modify) : $dolly;
}
public function setTimestamp($timestamp)
{
$zone = $this->getTimezone();
$this->__construct('@' . $timestamp);
return $this->setTimeZone($zone);
}
public function getTimestamp()
{
$ts = $this->format('U');
return is_float($tmp = $ts * 1) ? $ts : $tmp;
}
}
Nette-2.1.0/Nette/common/Environment.php 100777 0 0 16367 12261522617 13335 0 expand($value);
}
self::getContext()->parameters[$name] = $value;
}
/**
* Returns the value of an environment variable or $default if there is no element set.
* @param string
* @param mixed default value to use if key not found
* @return mixed
* @throws InvalidStateException
*/
public static function getVariable($name, $default = NULL)
{
if (isset(self::getContext()->parameters[$name])) {
return self::getContext()->parameters[$name];
} elseif (func_num_args() > 1) {
return $default;
} else {
throw new InvalidStateException("Unknown environment variable '$name'.");
}
}
/**
* Returns the all environment variables.
* @return array
*/
public static function getVariables()
{
return self::getContext()->parameters;
}
/**
* Returns expanded variable.
* @param string
* @return string
* @throws InvalidStateException
*/
public static function expand($s)
{
return self::getContext()->expand($s);
}
/********************* context ****************d*g**/
/**
* Sets initial instance of context.
* @return void
*/
public static function setContext(DI\Container $context)
{
if (self::$createdAt) {
throw new Nette\InvalidStateException('Configurator & SystemContainer has already been created automatically by Nette\Environment at ' . self::$createdAt);
}
self::$context = $context;
}
/**
* Get initial instance of context.
* @return \SystemContainer|Nette\DI\Container
*/
public static function getContext()
{
if (self::$context === NULL) {
self::loadConfig();
}
return self::$context;
}
/**
* Gets the service object of the specified type.
* @param string service name
* @return object
*/
public static function getService($name)
{
return self::getContext()->getService($name);
}
/**
* Calling to undefined static method.
* @param string method name
* @param array arguments
* @return object service
*/
public static function __callStatic($name, $args)
{
if (!$args && strncasecmp($name, 'get', 3) === 0) {
return self::getService(lcfirst(substr($name, 3)));
} else {
throw new MemberAccessException("Call to undefined static method Nette\\Environment::$name().");
}
}
/**
* @return Nette\Http\Request
*/
public static function getHttpRequest()
{
return self::getContext()->getByType('Nette\Http\IRequest');
}
/**
* @return Nette\Http\Context
*/
public static function getHttpContext()
{
return self::getContext()->getByType('Nette\Http\Context');
}
/**
* @return Nette\Http\Response
*/
public static function getHttpResponse()
{
return self::getContext()->getByType('Nette\Http\IResponse');
}
/**
* @return Nette\Application\Application
*/
public static function getApplication()
{
return self::getContext()->getByType('Nette\Application\Application');
}
/**
* @return Nette\Security\User
*/
public static function getUser()
{
return self::getContext()->getByType('Nette\Security\User');
}
/**
* @return Nette\Loaders\RobotLoader
*/
public static function getRobotLoader()
{
return self::getContext()->getByType('Nette\Loaders\RobotLoader');
}
/********************* service factories ****************d*g**/
/**
* @param string
* @return Nette\Caching\Cache
*/
public static function getCache($namespace = '')
{
return new Caching\Cache(self::getContext()->getByType('Nette\Caching\IStorage'), $namespace);
}
/**
* Returns instance of session or session namespace.
* @param string
* @return Nette\Http\Session
*/
public static function getSession($namespace = NULL)
{
return $namespace === NULL
? self::getContext()->getByType('Nette\Http\Session')
: self::getContext()->getByType('Nette\Http\Session')->getSection($namespace);
}
/********************* global configuration ****************d*g**/
/**
* Loads global configuration from file and process it.
* @param string
* @param string
* @return Nette\ArrayHash
*/
public static function loadConfig($file = NULL, $section = NULL)
{
if (self::$createdAt) {
throw new Nette\InvalidStateException('Nette\Configurator has already been created automatically by Nette\Environment at ' . self::$createdAt);
} elseif (!defined('TEMP_DIR')) {
throw new Nette\InvalidStateException('Nette\Environment requires constant TEMP_DIR with path to temporary directory.');
}
$configurator = new Nette\Configurator;
$configurator
->setDebugMode(!self::isProduction())
->setTempDirectory(TEMP_DIR)
->addParameters(array('container' => array('class' => 'EnvironmentContainer')));
if ($file) {
$configurator->addConfig($file, $section);
}
self::$context = $configurator->createContainer();
self::$createdAt = '?';
foreach (debug_backtrace(FALSE) as $row) {
if (isset($row['file']) && $row['file'] !== __FILE__ && is_file($row['file'])) {
self::$createdAt = "$row[file]:$row[line]";
break;
}
}
return self::getConfig();
}
/**
* Returns the global configuration.
* @param string key
* @param mixed default value
* @return mixed
*/
public static function getConfig($key = NULL, $default = NULL)
{
$params = Nette\ArrayHash::from(self::getContext()->parameters);
if (func_num_args()) {
return isset($params[$key]) ? $params[$key] : $default;
} else {
return $params;
}
}
}
Nette-2.1.0/Nette/common/exceptions.php 100777 0 0 5670 12261522617 13165 0 context = $context;
trigger_error(__CLASS__ . ' is deprecated, use ErrorException.', E_USER_DEPRECATED);
}
}
Nette-2.1.0/Nette/common/Framework.php 100777 0 0 1130 12261522617 12724 0 frozen = TRUE;
}
/**
* Is the object unmodifiable?
* @return bool
*/
public function isFrozen()
{
return $this->frozen;
}
/**
* Creates a modifiable clone of the object.
* @return void
*/
public function __clone()
{
$this->frozen = FALSE;
}
/**
* @return void
*/
protected function updating()
{
if ($this->frozen) {
$class = get_class($this);
throw new InvalidStateException("Cannot modify a frozen object $class.");
}
}
}
Nette-2.1.0/Nette/common/IFreezable.php 100777 0 0 776 12261522617 12776 0
* $image = Image::fromFile('nette.jpg');
* $image->resize(150, 100);
* $image->sharpen();
* $image->send();
*
*
* @author David Grudl
*
* @method void alphaBlending(bool $on)
* @method void antialias(bool $on)
* @method void arc($x, $y, $w, $h, $s, $e, $color)
* @method void char($font, $x, $y, $char, $color)
* @method void charUp($font, $x, $y, $char, $color)
* @method int colorAllocate($red, $green, $blue)
* @method int colorAllocateAlpha($red, $green, $blue, $alpha)
* @method int colorAt($x, $y)
* @method int colorClosest($red, $green, $blue)
* @method int colorClosestAlpha($red, $green, $blue, $alpha)
* @method int colorClosestHWB($red, $green, $blue)
* @method void colorDeallocate($color)
* @method int colorExact($red, $green, $blue)
* @method int colorExactAlpha($red, $green, $blue, $alpha)
* @method void colorMatch(Image $image2)
* @method int colorResolve($red, $green, $blue)
* @method int colorResolveAlpha($red, $green, $blue, $alpha)
* @method void colorSet($index, $red, $green, $blue)
* @method array colorsForIndex($index)
* @method int colorsTotal()
* @method int colorTransparent([$color])
* @method void convolution(array $matrix, float $div, float $offset)
* @method void copy(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH)
* @method void copyMerge(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH, $opacity)
* @method void copyMergeGray(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH, $opacity)
* @method void copyResampled(Image $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH)
* @method void copyResized(Image $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH)
* @method void dashedLine($x1, $y1, $x2, $y2, $color)
* @method void ellipse($cx, $cy, $w, $h, $color)
* @method void fill($x, $y, $color)
* @method void filledArc($cx, $cy, $w, $h, $s, $e, $color, $style)
* @method void filledEllipse($cx, $cy, $w, $h, $color)
* @method void filledPolygon(array $points, $numPoints, $color)
* @method void filledRectangle($x1, $y1, $x2, $y2, $color)
* @method void fillToBorder($x, $y, $border, $color)
* @method void filter($filtertype [, ...])
* @method int fontHeight($font)
* @method int fontWidth($font)
* @method array ftBBox($size, $angle, string $fontFile, string $text [, array $extrainfo])
* @method array ftText($size, $angle, $x, $y, $col, string $fontFile, string $text [, array $extrainfo])
* @method void gammaCorrect(float $inputgamma, float $outputgamma)
* @method int interlace([$interlace])
* @method bool isTrueColor()
* @method void layerEffect($effect)
* @method void line($x1, $y1, $x2, $y2, $color)
* @method int loadFont(string $file)
* @method void paletteCopy(Image $source)
* @method void polygon(array $points, $numPoints, $color)
* @method array psBBox(string $text, $font, $size [, $space] [, $tightness] [, float $angle])
* @method void psEncodeFont($fontIndex, string $encodingfile)
* @method void psExtendFont($fontIndex, float $extend)
* @method void psFreeFont($fontindex)
* @method resource psLoadFont(string $filename)
* @method void psSlantFont($fontIndex, float $slant)
* @method array psText(string $text, $font, $size, $color, $backgroundColor, $x, $y [, $space] [, $tightness] [, float $angle] [, $antialiasSteps])
* @method void rectangle($x1, $y1, $x2, $y2, $col)
* @method Image rotate(float $angle, $backgroundColor)
* @method void saveAlpha(bool $saveflag)
* @method void setBrush(Image $brush)
* @method void setPixel($x, $y, $color)
* @method void setStyle(array $style)
* @method void setThickness($thickness)
* @method void setTile(Image $tile)
* @method void string($font, $x, $y, string $s, $col)
* @method void stringUp($font, $x, $y, string $s, $col)
* @method void trueColorToPalette(bool $dither, $ncolors)
* @method array ttfBBox($size, $angle, string $fontfile, string $text)
* @method array ttfText($size, $angle, $x, $y, $color, string $fontfile, string $text)
* @method int types()
* @property-read int $width
* @property-read int $height
* @property-read resource $imageResource
*/
class Image extends Object
{
/** {@link resize()} only shrinks images */
const SHRINK_ONLY = 1;
/** {@link resize()} will ignore aspect ratio */
const STRETCH = 2;
/** {@link resize()} fits in given area so its dimensions are less than or equal to the required dimensions */
const FIT = 0;
/** {@link resize()} fills given area so its dimensions are greater than or equal to the required dimensions */
const FILL = 4;
/** {@link resize()} fills given area exactly */
const EXACT = 8;
/** @int image types {@link send()} */
const JPEG = IMAGETYPE_JPEG,
PNG = IMAGETYPE_PNG,
GIF = IMAGETYPE_GIF;
const EMPTY_GIF = "GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;";
/** @deprecated */
const ENLARGE = 0;
/** @var resource */
private $image;
/**
* Returns RGB color.
* @param int red 0..255
* @param int green 0..255
* @param int blue 0..255
* @param int transparency 0..127
* @return array
*/
public static function rgb($red, $green, $blue, $transparency = 0)
{
return array(
'red' => max(0, min(255, (int) $red)),
'green' => max(0, min(255, (int) $green)),
'blue' => max(0, min(255, (int) $blue)),
'alpha' => max(0, min(127, (int) $transparency)),
);
}
/**
* Opens image from file.
* @param string
* @param mixed detected image format
* @return Image
*/
public static function fromFile($file, & $format = NULL)
{
if (!extension_loaded('gd')) {
throw new NotSupportedException("PHP extension GD is not loaded.");
}
$info = @getimagesize($file); // @ - files smaller than 12 bytes causes read error
switch ($format = $info[2]) {
case self::JPEG:
return new static(imagecreatefromjpeg($file));
case self::PNG:
return new static(imagecreatefrompng($file));
case self::GIF:
return new static(imagecreatefromgif($file));
default:
throw new UnknownImageFileException("Unknown image type or file '$file' not found.");
}
}
/**
* Get format from the image stream in the string.
* @param string
* @return mixed detected image format
*/
public static function getFormatFromString($s)
{
$types = array('image/jpeg' => self::JPEG, 'image/gif' => self::GIF, 'image/png' => self::PNG);
$type = Utils\MimeTypeDetector::fromString($s);
return isset($types[$type]) ? $types[$type] : NULL;
}
/**
* Create a new image from the image stream in the string.
* @param string
* @param mixed detected image format
* @return Image
*/
public static function fromString($s, & $format = NULL)
{
if (!extension_loaded('gd')) {
throw new NotSupportedException("PHP extension GD is not loaded.");
}
$format = static::getFormatFromString($s);
return new static(imagecreatefromstring($s));
}
/**
* Creates blank image.
* @param int
* @param int
* @param array
* @return Image
*/
public static function fromBlank($width, $height, $color = NULL)
{
if (!extension_loaded('gd')) {
throw new NotSupportedException("PHP extension GD is not loaded.");
}
$width = (int) $width;
$height = (int) $height;
if ($width < 1 || $height < 1) {
throw new InvalidArgumentException('Image width and height must be greater than zero.');
}
$image = imagecreatetruecolor($width, $height);
if (is_array($color)) {
$color += array('alpha' => 0);
$color = imagecolorallocatealpha($image, $color['red'], $color['green'], $color['blue'], $color['alpha']);
imagealphablending($image, FALSE);
imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $color);
imagealphablending($image, TRUE);
}
return new static($image);
}
/**
* Wraps GD image.
* @param resource
*/
public function __construct($image)
{
$this->setImageResource($image);
imagesavealpha($image, TRUE);
}
/**
* Returns image width.
* @return int
*/
public function getWidth()
{
return imagesx($this->image);
}
/**
* Returns image height.
* @return int
*/
public function getHeight()
{
return imagesy($this->image);
}
/**
* Sets image resource.
* @param resource
* @return self
*/
protected function setImageResource($image)
{
if (!is_resource($image) || get_resource_type($image) !== 'gd') {
throw new InvalidArgumentException('Image is not valid.');
}
$this->image = $image;
return $this;
}
/**
* Returns image GD resource.
* @return resource
*/
public function getImageResource()
{
return $this->image;
}
/**
* Resizes image.
* @param mixed width in pixels or percent
* @param mixed height in pixels or percent
* @param int flags
* @return self
*/
public function resize($width, $height, $flags = self::FIT)
{
if ($flags & self::EXACT) {
return $this->resize($width, $height, self::FILL)->crop('50%', '50%', $width, $height);
}
list($newWidth, $newHeight) = static::calculateSize($this->getWidth(), $this->getHeight(), $width, $height, $flags);
if ($newWidth !== $this->getWidth() || $newHeight !== $this->getHeight()) { // resize
$newImage = static::fromBlank($newWidth, $newHeight, self::RGB(0, 0, 0, 127))->getImageResource();
imagecopyresampled(
$newImage, $this->getImageResource(),
0, 0, 0, 0,
$newWidth, $newHeight, $this->getWidth(), $this->getHeight()
);
$this->image = $newImage;
}
if ($width < 0 || $height < 0) { // flip is processed in two steps for better quality
$newImage = static::fromBlank($newWidth, $newHeight, self::RGB(0, 0, 0, 127))->getImageResource();
imagecopyresampled(
$newImage, $this->getImageResource(),
0, 0, $width < 0 ? $newWidth - 1 : 0, $height < 0 ? $newHeight - 1 : 0,
$newWidth, $newHeight, $width < 0 ? -$newWidth : $newWidth, $height < 0 ? -$newHeight : $newHeight
);
$this->image = $newImage;
}
return $this;
}
/**
* Calculates dimensions of resized image.
* @param mixed source width
* @param mixed source height
* @param mixed width in pixels or percent
* @param mixed height in pixels or percent
* @param int flags
* @return array
*/
public static function calculateSize($srcWidth, $srcHeight, $newWidth, $newHeight, $flags = self::FIT)
{
if (substr($newWidth, -1) === '%') {
$newWidth = round($srcWidth / 100 * abs($newWidth));
$percents = TRUE;
} else {
$newWidth = (int) abs($newWidth);
}
if (substr($newHeight, -1) === '%') {
$newHeight = round($srcHeight / 100 * abs($newHeight));
$flags |= empty($percents) ? 0 : self::STRETCH;
} else {
$newHeight = (int) abs($newHeight);
}
if ($flags & self::STRETCH) { // non-proportional
if (empty($newWidth) || empty($newHeight)) {
throw new InvalidArgumentException('For stretching must be both width and height specified.');
}
if ($flags & self::SHRINK_ONLY) {
$newWidth = round($srcWidth * min(1, $newWidth / $srcWidth));
$newHeight = round($srcHeight * min(1, $newHeight / $srcHeight));
}
} else { // proportional
if (empty($newWidth) && empty($newHeight)) {
throw new InvalidArgumentException('At least width or height must be specified.');
}
$scale = array();
if ($newWidth > 0) { // fit width
$scale[] = $newWidth / $srcWidth;
}
if ($newHeight > 0) { // fit height
$scale[] = $newHeight / $srcHeight;
}
if ($flags & self::FILL) {
$scale = array(max($scale));
}
if ($flags & self::SHRINK_ONLY) {
$scale[] = 1;
}
$scale = min($scale);
$newWidth = round($srcWidth * $scale);
$newHeight = round($srcHeight * $scale);
}
return array(max((int) $newWidth, 1), max((int) $newHeight, 1));
}
/**
* Crops image.
* @param mixed x-offset in pixels or percent
* @param mixed y-offset in pixels or percent
* @param mixed width in pixels or percent
* @param mixed height in pixels or percent
* @return self
*/
public function crop($left, $top, $width, $height)
{
list($left, $top, $width, $height) = static::calculateCutout($this->getWidth(), $this->getHeight(), $left, $top, $width, $height);
$newImage = static::fromBlank($width, $height, self::RGB(0, 0, 0, 127))->getImageResource();
imagecopy($newImage, $this->getImageResource(), 0, 0, $left, $top, $width, $height);
$this->image = $newImage;
return $this;
}
/**
* Calculates dimensions of cutout in image.
* @param mixed source width
* @param mixed source height
* @param mixed x-offset in pixels or percent
* @param mixed y-offset in pixels or percent
* @param mixed width in pixels or percent
* @param mixed height in pixels or percent
* @return array
*/
public static function calculateCutout($srcWidth, $srcHeight, $left, $top, $newWidth, $newHeight)
{
if (substr($newWidth, -1) === '%') {
$newWidth = round($srcWidth / 100 * $newWidth);
}
if (substr($newHeight, -1) === '%') {
$newHeight = round($srcHeight / 100 * $newHeight);
}
if (substr($left, -1) === '%') {
$left = round(($srcWidth - $newWidth) / 100 * $left);
}
if (substr($top, -1) === '%') {
$top = round(($srcHeight - $newHeight) / 100 * $top);
}
if ($left < 0) {
$newWidth += $left; $left = 0;
}
if ($top < 0) {
$newHeight += $top; $top = 0;
}
$newWidth = min((int) $newWidth, $srcWidth - $left);
$newHeight = min((int) $newHeight, $srcHeight - $top);
return array($left, $top, $newWidth, $newHeight);
}
/**
* Sharpen image.
* @return self
*/
public function sharpen()
{
imageconvolution($this->getImageResource(), array( // my magic numbers ;)
array( -1, -1, -1 ),
array( -1, 24, -1 ),
array( -1, -1, -1 ),
), 16, 0);
return $this;
}
/**
* Puts another image into this image.
* @param Image
* @param mixed x-coordinate in pixels or percent
* @param mixed y-coordinate in pixels or percent
* @param int opacity 0..100
* @return self
*/
public function place(Image $image, $left = 0, $top = 0, $opacity = 100)
{
$opacity = max(0, min(100, (int) $opacity));
if (substr($left, -1) === '%') {
$left = round(($this->getWidth() - $image->getWidth()) / 100 * $left);
}
if (substr($top, -1) === '%') {
$top = round(($this->getHeight() - $image->getHeight()) / 100 * $top);
}
if ($opacity === 100) {
imagecopy(
$this->getImageResource(), $image->getImageResource(),
$left, $top, 0, 0, $image->getWidth(), $image->getHeight()
);
} elseif ($opacity <> 0) {
imagecopymerge(
$this->getImageResource(), $image->getImageResource(),
$left, $top, 0, 0, $image->getWidth(), $image->getHeight(),
$opacity
);
}
return $this;
}
/**
* Saves image to the file.
* @param string filename
* @param int quality 0..100 (for JPEG and PNG)
* @param int optional image type
* @return bool TRUE on success or FALSE on failure.
*/
public function save($file = NULL, $quality = NULL, $type = NULL)
{
if ($type === NULL) {
switch (strtolower(pathinfo($file, PATHINFO_EXTENSION))) {
case 'jpg':
case 'jpeg':
$type = self::JPEG;
break;
case 'png':
$type = self::PNG;
break;
case 'gif':
$type = self::GIF;
}
}
switch ($type) {
case self::JPEG:
$quality = $quality === NULL ? 85 : max(0, min(100, (int) $quality));
return imagejpeg($this->getImageResource(), $file, $quality);
case self::PNG:
$quality = $quality === NULL ? 9 : max(0, min(9, (int) $quality));
return imagepng($this->getImageResource(), $file, $quality);
case self::GIF:
return imagegif($this->getImageResource(), $file);
default:
throw new InvalidArgumentException("Unsupported image type.");
}
}
/**
* Outputs image to string.
* @param int image type
* @param int quality 0..100 (for JPEG and PNG)
* @return string
*/
public function toString($type = self::JPEG, $quality = NULL)
{
ob_start();
$this->save(NULL, $quality, $type);
return ob_get_clean();
}
/**
* Outputs image to string.
* @return string
*/
public function __toString()
{
try {
return $this->toString();
} catch (\Exception $e) {
trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
}
}
/**
* Outputs image to browser.
* @param int image type
* @param int quality 0..100 (for JPEG and PNG)
* @return bool TRUE on success or FALSE on failure.
*/
public function send($type = self::JPEG, $quality = NULL)
{
if ($type !== self::GIF && $type !== self::PNG && $type !== self::JPEG) {
throw new InvalidArgumentException("Unsupported image type.");
}
header('Content-Type: ' . image_type_to_mime_type($type));
return $this->save(NULL, $quality, $type);
}
/**
* Call to undefined method.
*
* @param string method name
* @param array arguments
* @return mixed
* @throws MemberAccessException
*/
public function __call($name, $args)
{
$function = 'image' . $name;
if (function_exists($function)) {
foreach ($args as $key => $value) {
if ($value instanceof self) {
$args[$key] = $value->getImageResource();
} elseif (is_array($value) && isset($value['red'])) { // rgb
$args[$key] = imagecolorallocatealpha(
$this->getImageResource(),
$value['red'], $value['green'], $value['blue'], $value['alpha']
);
}
}
array_unshift($args, $this->getImageResource());
$res = call_user_func_array($function, $args);
return is_resource($res) && get_resource_type($res) === 'gd' ? $this->setImageResource($res) : $res;
}
return parent::__call($name, $args);
}
}
/**
* The exception that indicates invalid image file.
*/
class UnknownImageFileException extends \Exception
{
}
Nette-2.1.0/Nette/common/Object.php 100777 0 0 10222 12261522617 12217 0
* $val = $obj->label; // equivalent to $val = $obj->getLabel();
* $obj->label = 'Nette'; // equivalent to $obj->setLabel('Nette');
*
* Property names are case-sensitive, and they are written in the camelCaps
* or PascalCaps.
*
* Event functionality is provided by declaration of property named 'on{Something}'
* Multiple handlers are allowed.
*
* public $onClick; // declaration in class
* $this->onClick[] = 'callback'; // attaching event handler
* if (!empty($this->onClick)) ... // are there any handlers?
* $this->onClick($sender, $arg); // raises the event with arguments
*
*
* Adding method to class (i.e. to all instances) works similar to JavaScript
* prototype property. The syntax for adding a new method is:
*
* MyClass::extensionMethod('newMethod', function(MyClass $obj, $arg, ...) { ... });
* $obj = new MyClass;
* $obj->newMethod($x);
*
*
* @author David Grudl
*
* @property-read Nette\Reflection\ClassType $reflection
*/
abstract class Object
{
/**
* Access to reflection.
* @return Nette\Reflection\ClassType
*/
public static function getReflection()
{
return new Reflection\ClassType(get_called_class());
}
/**
* Call to undefined method.
* @param string method name
* @param array arguments
* @return mixed
* @throws MemberAccessException
*/
public function __call($name, $args)
{
return ObjectMixin::call($this, $name, $args);
}
/**
* Call to undefined static method.
* @param string method name (in lower case!)
* @param array arguments
* @return mixed
* @throws MemberAccessException
*/
public static function __callStatic($name, $args)
{
return ObjectMixin::callStatic(get_called_class(), $name, $args);
}
/**
* Adding method to class.
* @param string method name
* @param callable
* @return mixed
*/
public static function extensionMethod($name, $callback = NULL)
{
if (strpos($name, '::') === FALSE) {
$class = get_called_class();
} else {
list($class, $name) = explode('::', $name);
$rc = new \ReflectionClass($class);
$class = $rc->getName();
}
if ($callback === NULL) {
return ObjectMixin::getExtensionMethod($class, $name);
} else {
ObjectMixin::setExtensionMethod($class, $name, $callback);
}
}
/**
* Returns property value. Do not call directly.
* @param string property name
* @return mixed property value
* @throws MemberAccessException if the property is not defined.
*/
public function &__get($name)
{
return ObjectMixin::get($this, $name);
}
/**
* Sets value of a property. Do not call directly.
* @param string property name
* @param mixed property value
* @return void
* @throws MemberAccessException if the property is not defined or is read-only
*/
public function __set($name, $value)
{
ObjectMixin::set($this, $name, $value);
}
/**
* Is property defined?
* @param string property name
* @return bool
*/
public function __isset($name)
{
return ObjectMixin::has($this, $name);
}
/**
* Access to undeclared property.
* @param string property name
* @return void
* @throws MemberAccessException
*/
public function __unset($name)
{
ObjectMixin::remove($this, $name);
}
}
Nette-2.1.0/Nette/common/ObjectMixin.php 100777 0 0 25512 12261522617 13234 0 0 | bool | array) used by getMethods() */
private static $methods;
/** @var array (name => 'event' | TRUE) used by hasProperty() */
private static $props;
/** @var array (name => array(type => callback)) used by get|setExtensionMethod() */
private static $extMethods;
/**
* Static class - cannot be instantiated.
*/
final public function __construct()
{
throw new StaticClassException;
}
/**
* __call() implementation.
* @param object
* @param string
* @param array
* @return mixed
* @throws MemberAccessException
*/
public static function call($_this, $name, $args)
{
$class = get_class($_this);
$isProp = self::hasProperty($class, $name);
$methods = & self::getMethods($class);
if ($name === '') {
throw new MemberAccessException("Call to class '$class' method without name.");
} elseif ($isProp && $_this->$name instanceof \Closure) { // closure in property
return call_user_func_array($_this->$name, $args);
} elseif ($isProp === 'event') { // calling event handlers
if (is_array($_this->$name) || $_this->$name instanceof \Traversable) {
foreach ($_this->$name as $handler) {
Nette\Utils\Callback::invokeArgs($handler, $args);
}
} elseif ($_this->$name !== NULL) {
throw new UnexpectedValueException("Property $class::$$name must be array or NULL, " . gettype($_this->$name) ." given.");
}
} elseif (isset($methods[$name]) && $methods[$name] !== 0) { // magic @methods
list($op, $rp, $type) = $methods[$name];
if (!$rp) {
throw new MemberAccessException("Magic method $class::$name() has not corresponding property $$op.");
} elseif (count($args) !== ($op === 'get' ? 0 : 1)) {
throw new InvalidArgumentException("$class::$name() expects " . ($op === 'get' ? 'no' : '1') . ' argument, ' . count($args) . ' given.');
} elseif ($type && $args && !self::checkType($args[0], $type)) {
throw new InvalidArgumentException("Argument passed to $class::$name() must be $type, " . gettype($args[0]) . ' given.');
}
if ($op === 'get') {
return $rp->getValue($_this);
} elseif ($op === 'set') {
$rp->setValue($_this, $args[0]);
} elseif ($op === 'add') {
$val = $rp->getValue($_this);
$val[] = $args[0];
$rp->setValue($_this, $val);
}
return $_this;
} elseif ($cb = self::getExtensionMethod($class, $name)) { // extension methods
array_unshift($args, $_this);
return Nette\Utils\Callback::invokeArgs($cb, $args);
} else {
if (method_exists($class, $name)) { // called parent::$name()
$class = 'parent';
}
throw new MemberAccessException("Call to undefined method $class::$name().");
}
}
/**
* __callStatic() implementation.
* @param string
* @param string
* @param array
* @return void
* @throws MemberAccessException
*/
public static function callStatic($class, $method, $args)
{
throw new MemberAccessException("Call to undefined static method $class::$method().");
}
/**
* __get() implementation.
* @param object
* @param string property name
* @return mixed property value
* @throws MemberAccessException if the property is not defined.
*/
public static function & get($_this, $name)
{
$class = get_class($_this);
$uname = ucfirst($name);
$methods = & self::getMethods($class);
if ($name === '') {
throw new MemberAccessException("Cannot read a class '$class' property without name.");
} elseif (isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) { // property getter
if ($methods[$m] === 0) {
$rm = new \ReflectionMethod($class, $m);
$methods[$m] = $rm->returnsReference();
}
if ($methods[$m] === TRUE) {
return $_this->$m();
} else {
$val = $_this->$m();
return $val;
}
} elseif (isset($methods[$name])) { // public method as closure getter
if (PHP_VERSION_ID >= 50400) {
$rm = new \ReflectionMethod($class, $name);
$val = $rm->getClosure($_this);
} else {
$val = Nette\Utils\Callback::closure($_this, $name);
}
return $val;
} else { // strict class
$type = isset($methods['set' . $uname]) ? 'a write-only' : 'an undeclared';
throw new MemberAccessException("Cannot read $type property $class::\$$name.");
}
}
/**
* __set() implementation.
* @param object
* @param string property name
* @param mixed property value
* @return void
* @throws MemberAccessException if the property is not defined or is read-only
*/
public static function set($_this, $name, $value)
{
$class = get_class($_this);
$uname = ucfirst($name);
$methods = & self::getMethods($class);
if ($name === '') {
throw new MemberAccessException("Cannot write to a class '$class' property without name.");
} elseif (self::hasProperty($class, $name)) { // unsetted property
$_this->$name = $value;
} elseif (isset($methods[$m = 'set' . $uname])) { // property setter
$_this->$m($value);
} else { // strict class
$type = isset($methods['get' . $uname]) || isset($methods['is' . $uname])
? 'a read-only' : 'an undeclared';
throw new MemberAccessException("Cannot write to $type property $class::\$$name.");
}
}
/**
* __unset() implementation.
* @param object
* @param string property name
* @return void
* @throws MemberAccessException
*/
public static function remove($_this, $name)
{
$class = get_class($_this);
if (!self::hasProperty($class, $name)) { // strict class
throw new MemberAccessException("Cannot unset the property $class::\$$name.");
}
}
/**
* __isset() implementation.
* @param object
* @param string property name
* @return bool
*/
public static function has($_this, $name)
{
$name = ucfirst($name);
$methods = & self::getMethods(get_class($_this));
return $name !== '' && (isset($methods['get' . $name]) || isset($methods['is' . $name]));
}
/**
* Checks if the public non-static property exists.
* @return mixed
*/
private static function hasProperty($class, $name)
{
$prop = & self::$props[$class][$name];
if ($prop === NULL) {
$prop = FALSE;
try {
$rp = new \ReflectionProperty($class, $name);
if ($rp->isPublic() && !$rp->isStatic()) {
$prop = preg_match('#^on[A-Z]#', $name) ? 'event' : TRUE;
}
} catch (\ReflectionException $e) {}
}
return $prop;
}
/**
* Returns array of public (static, non-static and magic) methods.
* @return array
*/
private static function & getMethods($class)
{
if (!isset(self::$methods[$class])) {
self::$methods[$class] = array_fill_keys(get_class_methods($class), 0) + self::getMagicMethods($class);
if ($parent = get_parent_class($class)) {
self::$methods[$class] += self::getMethods($parent);
}
}
return self::$methods[$class];
}
/**
* Returns array of magic methods defined by annotation @method.
* @return array
*/
public static function getMagicMethods($class)
{
$rc = new \ReflectionClass($class);
preg_match_all('~^
[ \t*]* @method [ \t]+
(?: [^\s(]+ [ \t]+ )?
(set|get|is|add) ([A-Z]\w*) [ \t]*
(?: \( [ \t]* ([^)$\s]+) )?
()~mx', $rc->getDocComment(), $matches, PREG_SET_ORDER);
$methods = array();
foreach ($matches as $m) {
list(, $op, $prop, $type) = $m;
$name = $op . $prop;
$prop = strtolower($prop[0]) . substr($prop, 1) . ($op === 'add' ? 's' : '');
if ($rc->hasProperty($prop) && ($rp = $rc->getProperty($prop)) && !$rp->isStatic()) {
$rp->setAccessible(TRUE);
if ($op === 'get' || $op === 'is') {
$type = NULL; $op = 'get';
} elseif (!$type && preg_match('#@var[ \t]+(\S+)' . ($op === 'add' ? '\[\]#' : '#'), $rp->getDocComment(), $m)) {
$type = $m[1];
}
if ($rc->inNamespace() && preg_match('#^[A-Z]\w+(\[|\||\z)#', $type)) {
$type = $rc->getNamespaceName() . '\\' . $type;
}
$methods[$name] = array($op, $rp, $type);
} else {
$methods[$name] = array($prop, NULL, NULL);
}
}
return $methods;
}
/**
* Finds whether a variable is of expected type and do non-data-loss conversion.
* @return bool
*/
public static function checkType(& $val, $type)
{
if (strpos($type, '|') !== FALSE) {
$found = NULL;
foreach (explode('|', $type) as $type) {
$tmp = $val;
if (self::checkType($tmp, $type)) {
if ($val === $tmp) {
return TRUE;
}
$found[] = $tmp;
}
}
if ($found) {
$val = $found[0];
return TRUE;
}
return FALSE;
} elseif (substr($type, -2) === '[]') {
if (!is_array($val)) {
return FALSE;
}
$type = substr($type, 0, -2);
$res = array();
foreach ($val as $k => $v) {
if (!self::checkType($v, $type)) {
return FALSE;
}
$res[$k] = $v;
}
$val = $res;
return TRUE;
}
switch (strtolower($type)) {
case NULL:
case 'mixed':
return TRUE;
case 'bool':
case 'boolean':
return ($val === NULL || is_scalar($val)) && settype($val, 'bool');
case 'string':
return ($val === NULL || is_scalar($val) || (is_object($val) && method_exists($val, '__toString'))) && settype($val, 'string');
case 'int':
case 'integer':
return ($val === NULL || is_bool($val) || is_numeric($val)) && ((float) (int) $val === (float) $val) && settype($val, 'int');
case 'float':
return ($val === NULL || is_bool($val) || is_numeric($val)) && settype($val, 'float');
case 'scalar':
case 'array':
case 'object':
case 'callable':
case 'resource':
case 'null':
return call_user_func("is_$type", $val);
default:
return $val instanceof $type;
}
}
/**
* Adds a method to class.
* @param string
* @param string
* @param mixed callable
* @return void
*/
public static function setExtensionMethod($class, $name, $callback)
{
$name = strtolower($name);
self::$extMethods[$name][$class] = Nette\Utils\Callback::closure($callback);
self::$extMethods[$name][''] = NULL;
}
/**
* Returns extension method.
* @param string
* @param string
* @return mixed
*/
public static function getExtensionMethod($class, $name)
{
$list = & self::$extMethods[strtolower($name)];
$cache = & $list[''][$class];
if (isset($cache)) {
return $cache;
}
foreach (array($class) + class_parents($class) + class_implements($class) as $cl) {
if (isset($list[$cl])) {
return $cache = $list[$cl];
}
}
return $cache = FALSE;
}
}
Nette-2.1.0/Nette/common/shortcuts.php 100777 0 0 1561 12261522617 13035 0 [obj, depth, path, is_monitored?]] */
private $monitors = array();
public function __construct(IContainer $parent = NULL, $name = NULL)
{
if ($parent !== NULL) {
$parent->addComponent($this, $name);
} elseif (is_string($name)) {
$this->name = $name;
}
}
/**
* Lookup hierarchy for component specified by class or interface name.
* @param string class/interface type
* @param bool throw exception if component doesn't exist?
* @return IComponent
*/
public function lookup($type, $need = TRUE)
{
if (!isset($this->monitors[$type])) { // not monitored or not processed yet
$obj = $this->parent;
$path = self::NAME_SEPARATOR . $this->name;
$depth = 1;
while ($obj !== NULL) {
$parent = $obj->getParent();
if ($type ? $obj instanceof $type : $parent === NULL) {
break;
}
$path = self::NAME_SEPARATOR . $obj->getName() . $path;
$depth++;
$obj = $parent; // IComponent::getParent()
if ($obj === $this) {
$obj = NULL; // prevent cycling
}
}
if ($obj) {
$this->monitors[$type] = array($obj, $depth, substr($path, 1), FALSE);
} else {
$this->monitors[$type] = array(NULL, NULL, NULL, FALSE); // not found
}
}
if ($need && $this->monitors[$type][0] === NULL) {
throw new Nette\InvalidStateException("Component '$this->name' is not attached to '$type'.");
}
return $this->monitors[$type][0];
}
/**
* Lookup for component specified by class or interface name. Returns backtrace path.
* A path is the concatenation of component names separated by self::NAME_SEPARATOR.
* @param string class/interface type
* @param bool throw exception if component doesn't exist?
* @return string
*/
public function lookupPath($type, $need = TRUE)
{
$this->lookup($type, $need);
return $this->monitors[$type][2];
}
/**
* Starts monitoring.
* @param string class/interface type
* @return void
*/
public function monitor($type)
{
if (empty($this->monitors[$type][3])) {
if ($obj = $this->lookup($type, FALSE)) {
$this->attached($obj);
}
$this->monitors[$type][3] = TRUE; // mark as monitored
}
}
/**
* Stops monitoring.
* @param string class/interface type
* @return void
*/
public function unmonitor($type)
{
unset($this->monitors[$type]);
}
/**
* This method will be called when the component (or component's parent)
* becomes attached to a monitored object. Do not call this method yourself.
* @param IComponent
* @return void
*/
protected function attached($obj)
{
}
/**
* This method will be called before the component (or component's parent)
* becomes detached from a monitored object. Do not call this method yourself.
* @param IComponent
* @return void
*/
protected function detached($obj)
{
}
/********************* interface IComponent ****************d*g**/
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns the container if any.
* @return IContainer|NULL
*/
public function getParent()
{
return $this->parent;
}
/**
* Sets the parent of this component. This method is managed by containers and should
* not be called by applications
* @param IContainer New parent or null if this component is being removed from a parent
* @param string
* @return self
* @throws Nette\InvalidStateException
* @internal
*/
public function setParent(IContainer $parent = NULL, $name = NULL)
{
if ($parent === NULL && $this->parent === NULL && $name !== NULL) {
$this->name = $name; // just rename
return $this;
} elseif ($parent === $this->parent && $name === NULL) {
return $this; // nothing to do
}
// A component cannot be given a parent if it already has a parent.
if ($this->parent !== NULL && $parent !== NULL) {
throw new Nette\InvalidStateException("Component '$this->name' already has a parent.");
}
// remove from parent?
if ($parent === NULL) {
$this->refreshMonitors(0);
$this->parent = NULL;
} else { // add to parent
$this->validateParent($parent);
$this->parent = $parent;
if ($name !== NULL) {
$this->name = $name;
}
$tmp = array();
$this->refreshMonitors(0, $tmp);
}
return $this;
}
/**
* Is called by a component when it is about to be set new parent. Descendant can
* override this method to disallow a parent change by throwing an Nette\InvalidStateException
* @return void
* @throws Nette\InvalidStateException
*/
protected function validateParent(IContainer $parent)
{
}
/**
* Refreshes monitors.
* @param int
* @param array|NULL (array = attaching, NULL = detaching)
* @param array
* @return void
*/
private function refreshMonitors($depth, & $missing = NULL, & $listeners = array())
{
if ($this instanceof IContainer) {
foreach ($this->getComponents() as $component) {
if ($component instanceof Component) {
$component->refreshMonitors($depth + 1, $missing, $listeners);
}
}
}
if ($missing === NULL) { // detaching
foreach ($this->monitors as $type => $rec) {
if (isset($rec[1]) && $rec[1] > $depth) {
if ($rec[3]) { // monitored
$this->monitors[$type] = array(NULL, NULL, NULL, TRUE);
$listeners[] = array($this, $rec[0]);
} else { // not monitored, just randomly cached
unset($this->monitors[$type]);
}
}
}
} else { // attaching
foreach ($this->monitors as $type => $rec) {
if (isset($rec[0])) { // is in cache yet
continue;
} elseif (!$rec[3]) { // not monitored, just randomly cached
unset($this->monitors[$type]);
} elseif (isset($missing[$type])) { // known from previous lookup
$this->monitors[$type] = array(NULL, NULL, NULL, TRUE);
} else {
$this->monitors[$type] = NULL; // forces re-lookup
if ($obj = $this->lookup($type, FALSE)) {
$listeners[] = array($this, $obj);
} else {
$missing[$type] = TRUE;
}
$this->monitors[$type][3] = TRUE; // mark as monitored
}
}
}
if ($depth === 0) { // call listeners
$method = $missing === NULL ? 'detached' : 'attached';
foreach ($listeners as $item) {
$item[0]->$method($item[1]);
}
}
}
/********************* cloneable, serializable ****************d*g**/
/**
* Object cloning.
*/
public function __clone()
{
if ($this->parent === NULL) {
return;
} elseif ($this->parent instanceof Container) {
$this->parent = $this->parent->_isCloning();
if ($this->parent === NULL) { // not cloning
$this->refreshMonitors(0);
}
} else {
$this->parent = NULL;
$this->refreshMonitors(0);
}
}
/**
* Prevents serialization.
*/
public function __sleep()
{
throw new Nette\NotImplementedException('Object serialization is not supported by class ' . get_class($this));
}
/**
* Prevents unserialization.
*/
public function __wakeup()
{
throw new Nette\NotImplementedException('Object unserialization is not supported by class ' . get_class($this));
}
}
Nette-2.1.0/Nette/ComponentModel/Container.php 100777 0 0 14664 12261522617 14404 0 getName();
}
if (is_int($name)) {
$name = (string) $name;
} elseif (!is_string($name)) {
throw new Nette\InvalidArgumentException("Component name must be integer or string, " . gettype($name) . " given.");
} elseif (!preg_match('#^[a-zA-Z0-9_]+\z#', $name)) {
throw new Nette\InvalidArgumentException("Component name must be non-empty alphanumeric string, '$name' given.");
}
if (isset($this->components[$name])) {
throw new Nette\InvalidStateException("Component with name '$name' already exists.");
}
// check circular reference
$obj = $this;
do {
if ($obj === $component) {
throw new Nette\InvalidStateException("Circular reference detected while adding component '$name'.");
}
$obj = $obj->getParent();
} while ($obj !== NULL);
// user checking
$this->validateChildComponent($component);
try {
if (isset($this->components[$insertBefore])) {
$tmp = array();
foreach ($this->components as $k => $v) {
if ($k === $insertBefore) {
$tmp[$name] = $component;
}
$tmp[$k] = $v;
}
$this->components = $tmp;
} else {
$this->components[$name] = $component;
}
$component->setParent($this, $name);
} catch (\Exception $e) {
unset($this->components[$name]); // undo
throw $e;
}
return $this;
}
/**
* Removes a component from the IContainer.
* @return void
*/
public function removeComponent(IComponent $component)
{
$name = $component->getName();
if (!isset($this->components[$name]) || $this->components[$name] !== $component) {
throw new Nette\InvalidArgumentException("Component named '$name' is not located in this container.");
}
unset($this->components[$name]);
$component->setParent(NULL);
}
/**
* Returns component specified by name or path.
* @param string
* @param bool throw exception if component doesn't exist?
* @return IComponent|NULL
*/
public function getComponent($name, $need = TRUE)
{
if (is_int($name)) {
$name = (string) $name;
} elseif (!is_string($name)) {
throw new Nette\InvalidArgumentException("Component name must be integer or string, " . gettype($name) . " given.");
} else {
$a = strpos($name, self::NAME_SEPARATOR);
if ($a !== FALSE) {
$ext = (string) substr($name, $a + 1);
$name = substr($name, 0, $a);
}
if ($name === '') {
if ($need) {
throw new Nette\InvalidArgumentException("Component or subcomponent name must not be empty string.");
}
return;
}
}
if (!isset($this->components[$name])) {
$component = $this->createComponent($name);
if ($component instanceof IComponent && $component->getParent() === NULL) {
$this->addComponent($component, $name);
}
}
if (isset($this->components[$name])) {
if (!isset($ext)) {
return $this->components[$name];
} elseif ($this->components[$name] instanceof IContainer) {
return $this->components[$name]->getComponent($ext, $need);
} elseif ($need) {
throw new Nette\InvalidArgumentException("Component with name '$name' is not container and cannot have '$ext' component.");
}
} elseif ($need) {
throw new Nette\InvalidArgumentException("Component with name '$name' does not exist.");
}
}
/**
* Component factory. Delegates the creation of components to a createComponent method.
* @param string component name
* @return IComponent the created component (optionally)
*/
protected function createComponent($name)
{
$ucname = ucfirst($name);
$method = 'createComponent' . $ucname;
if ($ucname !== $name && method_exists($this, $method) && $this->getReflection()->getMethod($method)->getName() === $method) {
$component = $this->$method($name);
if (!$component instanceof IComponent && !isset($this->components[$name])) {
$class = get_class($this);
throw new Nette\UnexpectedValueException("Method $class::$method() did not return or create the desired component.");
}
return $component;
}
}
/**
* Iterates over components.
* @param bool recursive?
* @param string class types filter
* @return \ArrayIterator
*/
public function getComponents($deep = FALSE, $filterType = NULL)
{
$iterator = new RecursiveComponentIterator($this->components);
if ($deep) {
$deep = $deep > 0 ? \RecursiveIteratorIterator::SELF_FIRST : \RecursiveIteratorIterator::CHILD_FIRST;
$iterator = new \RecursiveIteratorIterator($iterator, $deep);
}
if ($filterType) {
$iterator = new Nette\Iterators\Filter($iterator, function($item) use ($filterType) {
return $item instanceof $filterType;
});
}
return $iterator;
}
/**
* Descendant can override this method to disallow insert a child by throwing an Nette\InvalidStateException.
* @return void
* @throws Nette\InvalidStateException
*/
protected function validateChildComponent(IComponent $child)
{
}
/********************* cloneable, serializable ****************d*g**/
/**
* Object cloning.
*/
public function __clone()
{
if ($this->components) {
$oldMyself = reset($this->components)->getParent();
$oldMyself->cloning = $this;
foreach ($this->components as $name => $component) {
$this->components[$name] = clone $component;
}
$oldMyself->cloning = NULL;
}
parent::__clone();
}
/**
* Is container cloning now?
* @return NULL|IComponent
* @internal
*/
public function _isCloning()
{
return $this->cloning;
}
}
Nette-2.1.0/Nette/ComponentModel/IComponent.php 100777 0 0 1357 12261522617 14510 0 current() instanceof IContainer;
}
/**
* The sub-iterator for the current element.
* @return \RecursiveIterator
*/
public function getChildren()
{
return $this->current()->getComponents();
}
/**
* Returns the count of elements.
* @return int
*/
public function count()
{
return iterator_count($this);
}
}
Nette-2.1.0/Nette/Database/ 40777 0 0 0 12261522617 10377 5 Nette-2.1.0/Nette/Database/Connection.php 100777 0 0 13415 12261522617 13333 0 4) { // compatibility
$options['driverClass'] = func_get_arg(4);
}
$this->params = array($dsn, $user, $password);
$this->options = (array) $options;
if (empty($options['lazy'])) {
$this->connect();
}
}
public function connect()
{
if ($this->pdo) {
return;
}
$this->pdo = new PDO($this->params[0], $this->params[1], $this->params[2], $this->options);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$class = empty($this->options['driverClass'])
? 'Nette\Database\Drivers\\' . ucfirst(str_replace('sql', 'Sql', $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME))) . 'Driver'
: $this->options['driverClass'];
$this->driver = new $class($this, $this->options);
$this->preprocessor = new SqlPreprocessor($this);
$this->onConnect($this);
}
/** @return string */
public function getDsn()
{
return $this->params[0];
}
/** @return PDO */
public function getPdo()
{
$this->connect();
return $this->pdo;
}
/** @return ISupplementalDriver */
public function getSupplementalDriver()
{
$this->connect();
return $this->driver;
}
/**
* @param string sequence object
* @return string
*/
public function getInsertId($name = NULL)
{
return $this->getPdo()->lastInsertId($name);
}
/**
* @param string string to be quoted
* @param int data type hint
* @return string
*/
public function quote($string, $type = PDO::PARAM_STR)
{
return $this->getPdo()->quote($string, $type);
}
/** @deprecated */
function beginTransaction()
{
$this->queryArgs('::beginTransaction', array());
}
/** @deprecated */
function commit()
{
$this->queryArgs('::commit', array());
}
/** @deprecated */
public function rollBack()
{
$this->queryArgs('::rollBack', array());
}
/** @deprecated */
public function query($statement)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args);
}
/** @deprecated */
function queryArgs($statement, array $params)
{
$this->connect();
if ($params) {
array_unshift($params, $statement);
list($statement, $params) = $this->preprocessor->process($params);
}
try {
$result = new ResultSet($this, $statement, $params);
} catch (\PDOException $e) {
$e->queryString = $statement;
$this->onQuery($this, $e);
throw $e;
}
$this->onQuery($this, $result);
return $result;
}
/********************* shortcuts ****************d*g**/
/** @deprecated */
function fetch($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetch();
}
/** @deprecated */
function fetchField($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetchField();
}
/** @deprecated */
function fetchPairs($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetchPairs();
}
/** @deprecated */
function fetchAll($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetchAll();
}
/** @deprecated */
static function literal($value)
{
$args = func_get_args();
return new SqlLiteral(array_shift($args), $args);
}
/********************* Selection ****************d*g**/
/** @deprecated */
function table($table)
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Database\Context::table() instead.', E_USER_DEPRECATED);
if (!$this->context) {
$this->context = new Context($this);
}
return $this->context->table($table);
}
/** @deprecated */
function setContext(Context $context)
{
$this->context = $context;
return $this;
}
/** @deprecated */
function getContext()
{
return $this->context;
}
/** @deprecated */
function setDatabaseReflection()
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Database\Context instead.', E_USER_DEPRECATED);
return $this;
}
/** @deprecated */
function setCacheStorage()
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Database\Context instead.', E_USER_DEPRECATED);
}
/** @deprecated */
function lastInsertId($name = NULL)
{
trigger_error(__METHOD__ . '() is deprecated; use getInsertId() instead.', E_USER_DEPRECATED);
return $this->getInsertId($name);
}
/** @deprecated */
function exec($statement)
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Database\Context::query()->getRowCount() instead.', E_USER_DEPRECATED);
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->getRowCount();
}
}
Nette-2.1.0/Nette/Database/Context.php 100777 0 0 7753 12261522617 12650 0 connection = $connection;
$this->reflection = $reflection ?: new Reflection\ConventionalReflection;
$this->cacheStorage = $cacheStorage;
}
/** @return void */
public function beginTransaction()
{
$this->queryArgs('::beginTransaction', array());
}
/** @return void */
public function commit()
{
$this->queryArgs('::commit', array());
}
/** @return void */
public function rollBack()
{
$this->queryArgs('::rollBack', array());
}
/**
* @param string sequence object
* @return string
*/
public function getInsertId($name = NULL)
{
return $this->connection->getInsertId($name);
}
/**
* Generates and executes SQL query.
* @param string statement
* @param mixed [parameters, ...]
* @return ResultSet
*/
public function query($statement)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args);
}
/**
* @param string statement
* @param array
* @return ResultSet
*/
public function queryArgs($statement, array $params)
{
$this->connection->connect();
if ($params) {
if (!$this->preprocessor) {
$this->preprocessor = new SqlPreprocessor($this->connection);
}
array_unshift($params, $statement);
list($statement, $params) = $this->preprocessor->process($params);
}
try {
$result = new ResultSet($this->connection, $statement, $params);
} catch (\PDOException $e) {
$e->queryString = $statement;
$this->connection->onQuery($this->connection, $e);
throw $e;
}
$this->connection->onQuery($this->connection, $result);
return $result;
}
/** @return Nette\Database\Table\Selection */
public function table($table)
{
return new Table\Selection($this->connection, $table, $this->reflection, $this->cacheStorage);
}
/** @return Connection */
public function getConnection()
{
return $this->connection;
}
/** @return IReflection */
public function getDatabaseReflection()
{
return $this->reflection;
}
/********************* shortcuts ****************d*g**/
/**
* Shortcut for query()->fetch()
* @param string statement
* @param mixed [parameters, ...]
* @return Row
*/
public function fetch($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetch();
}
/**
* Shortcut for query()->fetchField()
* @param string statement
* @param mixed [parameters, ...]
* @return mixed
*/
public function fetchField($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetchField();
}
/**
* Shortcut for query()->fetchPairs()
* @param string statement
* @param mixed [parameters, ...]
* @return array
*/
public function fetchPairs($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetchPairs();
}
/**
* Shortcut for query()->fetchAll()
* @param string statement
* @param mixed [parameters, ...]
* @return array
*/
public function fetchAll($args)
{
$args = func_get_args();
return $this->queryArgs(array_shift($args), $args)->fetchAll();
}
/**
* @return SqlLiteral
*/
public static function literal($value)
{
$args = func_get_args();
return new SqlLiteral(array_shift($args), $args);
}
}
Nette-2.1.0/Nette/Database/Diagnostics/ 40777 0 0 0 12261522617 12646 5 Nette-2.1.0/Nette/Database/Diagnostics/ConnectionPanel.php 100777 0 0 13373 12261522617 16565 0 onQuery[] = array($this, 'logQuery');
}
public function logQuery(Nette\Database\Connection $connection, $result)
{
if ($this->disabled) {
return;
}
$this->count++;
$source = NULL;
$trace = $result instanceof \PDOException ? $result->getTrace() : debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE);
foreach ($trace as $row) {
if (isset($row['file']) && is_file($row['file']) && !Nette\Diagnostics\Debugger::getBluescreen()->isCollapsed($row['file'])) {
if ((isset($row['function']) && strpos($row['function'], 'call_user_func') === 0)
|| (isset($row['class']) && is_subclass_of($row['class'], '\\Nette\\Database\\Connection'))
) {
continue;
}
$source = array($row['file'], (int) $row['line']);
break;
}
}
if ($result instanceof Nette\Database\ResultSet) {
$this->totalTime += $result->getTime();
if ($this->count < $this->maxQueries) {
$this->queries[] = array($connection, $result->getQueryString(), $result->getParameters(), $source, $result->getTime(), $result->getRowCount(), NULL);
}
} elseif ($result instanceof \PDOException && $this->count < $this->maxQueries) {
$this->queries[] = array($connection, $result->queryString, NULL, $source, NULL, NULL, $result->getMessage());
}
}
public static function renderException($e)
{
if (!$e instanceof \PDOException) {
return;
}
if (isset($e->queryString)) {
$sql = $e->queryString;
} elseif ($item = Nette\Diagnostics\Helpers::findTrace($e->getTrace(), 'PDO::prepare')) {
$sql = $item['args'][0];
}
return isset($sql) ? array(
'tab' => 'SQL',
'panel' => Helpers::dumpSql($sql),
) : NULL;
}
public function getTab()
{
return ''
. '
'
. $this->count . ' ' . ($this->count === 1 ? 'query' : 'queries')
. ($this->totalTime ? ' / ' . sprintf('%0.1f', $this->totalTime * 1000) . ' ms' : '')
. '';
}
public function getPanel()
{
$this->disabled = TRUE;
$s = '';
foreach ($this->queries as $query) {
list($connection, $sql, $params, $source, $time, $rows, $error) = $query;
$explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS()
if (!$error && $this->explain && preg_match('#\s*\(?\s*SELECT\s#iA', $sql)) {
try {
$cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN';
$explain = $connection->queryArgs("$cmd $sql", $params)->fetchAll();
} catch (\PDOException $e) {}
}
$s .= '';
if ($error) {
$s .= 'ERROR';
} elseif ($time !== NULL) {
$s .= sprintf('%0.3f', $time * 1000);
}
if ($explain) {
static $counter;
$counter++;
$s .= " explain";
}
$s .= ' | ' . Helpers::dumpSql($sql, $params);
if ($explain) {
$s .= "";
foreach ($explain[0] as $col => $foo) {
$s .= '' . htmlSpecialChars($col) . ' | ';
}
$s .= " ";
foreach ($explain as $row) {
$s .= "";
foreach ($row as $col) {
$s .= '' . htmlSpecialChars($col) . ' | ';
}
$s .= " ";
}
$s .= " ";
}
if ($source) {
$s .= Nette\Diagnostics\Helpers::editorLink($source[0], $source[1])->class('nette-DbConnectionPanel-source');
}
$s .= ' | ' . $rows . ' |
';
}
return $this->count ?
'
Queries: ' . $this->count
. ($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') . ', ' . htmlSpecialChars($this->name) . '
Time ms | SQL Query | Rows |
' . $s . '
'
. (count($this->queries) < $this->count ? '
...and more
' : '')
. '
' : '';
}
}
Nette-2.1.0/Nette/Database/Drivers/ 40777 0 0 0 12261522617 12015 5 Nette-2.1.0/Nette/Database/Drivers/MsSqlDriver.php 100777 0 0 6034 12261522617 15044 0 connection = $connection;
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
// @see http://msdn.microsoft.com/en-us/library/ms176027.aspx
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $name) . ']';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? '1' : '0';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
return $value->format("'Y-m-d H:i:s'");
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
$value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]'));
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($limit >= 0) {
$sql = preg_replace('#^\s*(SELECT|UPDATE|DELETE)#i', '$0 TOP ' . (int) $limit, $sql, 1, $count);
if (!$count) {
throw new Nette\InvalidArgumentException('SQL query must begin with SELECT, UPDATE or DELETE command.');
}
}
if ($offset) {
throw new Nette\NotSupportedException('Offset is not supported by this database.');
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
return Nette\Database\Helpers::detectTypes($statement);
}
/**
* @return bool
*/
public function isSupported($item)
{
return $item === self::SUPPORT_SUBSELECT;
}
}
Nette-2.1.0/Nette/Database/Drivers/MySqlDriver.php 100777 0 0 14526 12261522617 15077 0 character encoding to set (default is utf8)
* - sqlmode => see http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html
*/
public function __construct(Nette\Database\Connection $connection, array $options)
{
$this->connection = $connection;
$charset = isset($options['charset']) ? $options['charset'] : 'utf8';
if ($charset) {
$connection->query("SET NAMES '$charset'");
}
if (isset($options['sqlmode'])) {
$connection->query("SET sql_mode='$options[sqlmode]'");
}
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
// @see http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
return '`' . str_replace('`', '``', $name) . '`';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? '1' : '0';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
return $value->format("'Y-m-d H:i:s'");
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
$value = addcslashes(str_replace('\\', '\\\\', $value), "\x00\n\r\\'%_");
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($limit >= 0 || $offset > 0) {
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
$sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
. ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
/*$this->connection->query("
SELECT TABLE_NAME as name, TABLE_TYPE = 'VIEW' as view
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE()
");*/
$tables = array();
foreach ($this->connection->query('SHOW FULL TABLES') as $row) {
$tables[] = array(
'name' => $row[0],
'view' => isset($row[1]) && $row[1] === 'VIEW',
);
}
return $tables;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
/*$this->connection->query("
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = {$this->connection->quote($table)} AND TABLE_SCHEMA = DATABASE()
");*/
$columns = array();
foreach ($this->connection->query('SHOW FULL COLUMNS FROM ' . $this->delimite($table)) as $row) {
$type = explode('(', $row['Type']);
$columns[] = array(
'name' => $row['Field'],
'table' => $table,
'nativetype' => strtoupper($type[0]),
'size' => isset($type[1]) ? (int) $type[1] : NULL,
'unsigned' => (bool) strstr($row['Type'], 'unsigned'),
'nullable' => $row['Null'] === 'YES',
'default' => $row['Default'],
'autoincrement' => $row['Extra'] === 'auto_increment',
'primary' => $row['Key'] === 'PRI',
'vendor' => (array) $row,
);
}
return $columns;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
/*$this->connection->query("
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = {$this->connection->quote($table)} AND TABLE_SCHEMA = DATABASE()
AND REFERENCED_COLUMN_NAME IS NULL
");*/
$indexes = array();
foreach ($this->connection->query('SHOW INDEX FROM ' . $this->delimite($table)) as $row) {
$indexes[$row['Key_name']]['name'] = $row['Key_name'];
$indexes[$row['Key_name']]['unique'] = !$row['Non_unique'];
$indexes[$row['Key_name']]['primary'] = $row['Key_name'] === 'PRIMARY';
$indexes[$row['Key_name']]['columns'][$row['Seq_in_index'] - 1] = $row['Column_name'];
}
return array_values($indexes);
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
$keys = array();
$query = 'SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE '
. 'WHERE TABLE_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = ' . $this->connection->quote($table);
foreach ($this->connection->query($query) as $id => $row) {
$keys[$id]['name'] = $row['CONSTRAINT_NAME']; // foreign key name
$keys[$id]['local'] = $row['COLUMN_NAME']; // local columns
$keys[$id]['table'] = $row['REFERENCED_TABLE_NAME']; // referenced table
$keys[$id]['foreign'] = $row['REFERENCED_COLUMN_NAME']; // referenced columns
}
return array_values($keys);
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
$types = array();
$count = $statement->columnCount();
for ($col = 0; $col < $count; $col++) {
$meta = $statement->getColumnMeta($col);
if (isset($meta['native_type'])) {
$types[$meta['name']] = $type = Nette\Database\Helpers::detectType($meta['native_type']);
if ($type === Nette\Database\IReflection::FIELD_TIME) {
$types[$meta['name']] = Nette\Database\IReflection::FIELD_TIME_INTERVAL;
}
}
}
return $types;
}
/**
* @return bool
*/
public function isSupported($item)
{
// MULTI_COLUMN_AS_OR_COND due to mysql bugs:
// - http://bugs.mysql.com/bug.php?id=31188
// - http://bugs.mysql.com/bug.php?id=35819
// and more.
return $item === self::SUPPORT_SELECT_UNGROUPED_COLUMNS || $item === self::SUPPORT_MULTI_COLUMN_AS_OR_COND;
}
}
Nette-2.1.0/Nette/Database/Drivers/OciDriver.php 100777 0 0 6567 12261522617 14532 0 connection = $connection;
$this->fmtDateTime = isset($options['formatDateTime']) ? $options['formatDateTime'] : 'U';
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
// @see http://download.oracle.com/docs/cd/B10500_01/server.920/a96540/sql_elements9a.htm
return '"' . str_replace('"', '""', $name) . '"';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? '1' : '0';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
return $value->format($this->fmtDateTime);
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
throw new Nette\NotImplementedException;
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($offset > 0) {
// see http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
. ($limit >= 0 ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
. ') WHERE "__rnum" > '. (int) $offset;
} elseif ($limit >= 0) {
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
$tables = array();
foreach ($this->connection->query('SELECT * FROM cat') as $row) {
if ($row[1] === 'TABLE' || $row[1] === 'VIEW') {
$tables[] = array(
'name' => $row[0],
'view' => $row[1] === 'VIEW',
);
}
}
return $tables;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
return Nette\Database\Helpers::detectTypes($statement);
}
/**
* @return bool
*/
public function isSupported($item)
{
return $item === self::SUPPORT_SEQUENCE || $item === self::SUPPORT_SUBSELECT;
}
}
Nette-2.1.0/Nette/Database/Drivers/OdbcDriver.php 100777 0 0 5730 12261522617 14656 0 connection = $connection;
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $name) . ']';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? '1' : '0';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
return $value->format("#m/d/Y H:i:s#");
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
$value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]'));
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($limit >= 0) {
$sql = preg_replace('#^\s*(SELECT|UPDATE|DELETE)#i', '$0 TOP ' . (int) $limit, $sql, 1, $count);
if (!$count) {
throw new Nette\InvalidArgumentException('SQL query must begin with SELECT, UPDATE or DELETE command.');
}
}
if ($offset) {
throw new Nette\NotSupportedException('Offset is not supported by this database.');
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
throw new Nette\NotImplementedException;
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
return Nette\Database\Helpers::detectTypes($statement);
}
/**
* @return bool
*/
public function isSupported($item)
{
return $item === self::SUPPORT_SUBSELECT;
}
}
Nette-2.1.0/Nette/Database/Drivers/PgSqlDriver.php 100777 0 0 14346 12261522617 15060 0 connection = $connection;
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
// @see http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
return '"' . str_replace('"', '""', $name) . '"';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? 'TRUE' : 'FALSE';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
return $value->format("'Y-m-d H:i:s'");
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
$value = strtr($value, array("'" => "''", '\\' => '\\\\', '%' => '\\\\%', '_' => '\\\\_'));
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($limit >= 0) {
$sql .= ' LIMIT ' . (int) $limit;
}
if ($offset > 0) {
$sql .= ' OFFSET ' . (int) $offset;
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
$tables = array();
foreach ($this->connection->query("
SELECT
c.relname::varchar AS name,
c.relkind = 'v' AS view
FROM
pg_catalog.pg_class AS c
JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
WHERE
c.relkind IN ('r', 'v')
AND ARRAY[n.nspname] <@ pg_catalog.current_schemas(FALSE)
ORDER BY
c.relname
") as $row) {
$tables[] = (array) $row;
}
return $tables;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
$columns = array();
foreach ($this->connection->query("
SELECT
a.attname::varchar AS name,
c.relname::varchar AS table,
upper(t.typname) AS nativetype,
NULL AS size,
FALSE AS unsigned,
NOT (a.attnotnull OR t.typtype = 'd' AND t.typnotnull) AS nullable,
ad.adsrc::varchar AS default,
coalesce(co.contype = 'p' AND strpos(ad.adsrc, 'nextval') = 1, FALSE) AS autoincrement,
coalesce(co.contype = 'p', FALSE) AS primary,
substring(ad.adsrc from 'nextval[(]''\"?([^''\"]+)') AS sequence
FROM
pg_catalog.pg_attribute AS a
JOIN pg_catalog.pg_class AS c ON a.attrelid = c.oid
JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
JOIN pg_catalog.pg_type AS t ON a.atttypid = t.oid
LEFT JOIN pg_catalog.pg_attrdef AS ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum
LEFT JOIN pg_catalog.pg_constraint AS co ON co.connamespace = n.oid AND contype = 'p' AND co.conrelid = c.oid AND a.attnum = ANY(co.conkey)
WHERE
c.relkind IN ('r', 'v')
AND c.relname::varchar = {$this->connection->quote($table)}
AND ARRAY[n.nspname] <@ pg_catalog.current_schemas(FALSE)
AND a.attnum > 0
AND NOT a.attisdropped
ORDER BY
a.attnum
") as $row) {
$column = (array) $row;
$column['vendor'] = $column;
unset($column['sequence']);
$columns[] = $column;
}
return $columns;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
$indexes = array();
foreach ($this->connection->query("
SELECT
c2.relname::varchar AS name,
i.indisunique AS unique,
i.indisprimary AS primary,
a.attname::varchar AS column
FROM
pg_catalog.pg_class AS c1
JOIN pg_catalog.pg_namespace AS n ON c1.relnamespace = n.oid
JOIN pg_catalog.pg_index AS i ON c1.oid = i.indrelid
JOIN pg_catalog.pg_class AS c2 ON i.indexrelid = c2.oid
LEFT JOIN pg_catalog.pg_attribute AS a ON c1.oid = a.attrelid AND a.attnum = ANY(i.indkey)
WHERE
ARRAY[n.nspname] <@ pg_catalog.current_schemas(FALSE)
AND c1.relkind = 'r'
AND c1.relname = {$this->connection->quote($table)}
") as $row) {
$indexes[$row['name']]['name'] = $row['name'];
$indexes[$row['name']]['unique'] = $row['unique'];
$indexes[$row['name']]['primary'] = $row['primary'];
$indexes[$row['name']]['columns'][] = $row['column'];
}
return array_values($indexes);
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
/* Does't work with multicolumn foreign keys */
return $this->connection->query("
SELECT
co.conname::varchar AS name,
al.attname::varchar AS local,
cf.relname::varchar AS table,
af.attname::varchar AS foreign
FROM
pg_catalog.pg_constraint AS co
JOIN pg_catalog.pg_namespace AS n ON co.connamespace = n.oid
JOIN pg_catalog.pg_class AS cl ON co.conrelid = cl.oid
JOIN pg_catalog.pg_class AS cf ON co.confrelid = cf.oid
JOIN pg_catalog.pg_attribute AS al ON al.attrelid = cl.oid AND al.attnum = co.conkey[1]
JOIN pg_catalog.pg_attribute AS af ON af.attrelid = cf.oid AND af.attnum = co.confkey[1]
WHERE
ARRAY[n.nspname] <@ pg_catalog.current_schemas(FALSE)
AND co.contype = 'f'
AND cl.relname = {$this->connection->quote($table)}
")->fetchAll();
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
return Nette\Database\Helpers::detectTypes($statement);
}
/**
* @return bool
*/
public function isSupported($item)
{
return $item === self::SUPPORT_SEQUENCE || $item === self::SUPPORT_SUBSELECT;
}
}
Nette-2.1.0/Nette/Database/Drivers/Sqlite2Driver.php 100777 0 0 1270 12261522617 15325 0 connection = $connection;
$this->fmtDateTime = isset($options['formatDateTime']) ? $options['formatDateTime'] : 'U';
//$connection->query('PRAGMA foreign_keys = ON');
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
return '[' . strtr($name, '[]', ' ') . ']';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? '1' : '0';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
return $value->format($this->fmtDateTime);
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
$value = addcslashes(substr($this->connection->quote($value), 1, -1), '%_\\');
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'") . " ESCAPE '\\'";
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($limit >= 0 || $offset > 0) {
$sql .= ' LIMIT ' . (int) $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
foreach ($row as $key => $value) {
unset($row[$key]);
if ($key[0] === '[' || $key[0] === '"') {
$key = substr($key, 1, -1);
}
$row[$key] = $value;
}
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
$tables = array();
foreach ($this->connection->query("
SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
UNION ALL
SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
ORDER BY name
") as $row) {
$tables[] = array(
'name' => $row->name,
'view' => (bool) $row->view,
);
}
return $tables;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
$meta = $this->connection->query("
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->connection->quote($table)}
UNION ALL
SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->connection->quote($table)}
")->fetch();
$columns = array();
foreach ($this->connection->query("PRAGMA table_info({$this->delimite($table)})") as $row) {
$column = $row['name'];
$pattern = "/(\"$column\"|\[$column\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";
$type = explode('(', $row['type']);
$columns[] = array(
'name' => $column,
'table' => $table,
'nativetype' => strtoupper($type[0]),
'size' => isset($type[1]) ? (int) $type[1] : NULL,
'unsigned' => FALSE,
'nullable' => $row['notnull'] == '0',
'default' => $row['dflt_value'],
'autoincrement' => (bool) preg_match($pattern, $meta['sql']),
'primary' => $row['pk'] == '1',
'vendor' => (array) $row,
);
}
return $columns;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
$indexes = array();
foreach ($this->connection->query("PRAGMA index_list({$this->delimite($table)})") as $row) {
$indexes[$row['name']]['name'] = $row['name'];
$indexes[$row['name']]['unique'] = (bool) $row['unique'];
$indexes[$row['name']]['primary'] = FALSE;
}
foreach ($indexes as $index => $values) {
$res = $this->connection->query("PRAGMA index_info({$this->delimite($index)})");
while ($row = $res->fetch(TRUE)) {
$indexes[$index]['columns'][$row['seqno']] = $row['name'];
}
}
$columns = $this->getColumns($table);
foreach ($indexes as $index => $values) {
$column = $indexes[$index]['columns'][0];
foreach ($columns as $info) {
if ($column == $info['name']) {
$indexes[$index]['primary'] = (bool) $info['primary'];
break;
}
}
}
if (!$indexes) { // @see http://www.sqlite.org/lang_createtable.html#rowid
foreach ($columns as $column) {
if ($column['vendor']['pk']) {
$indexes[] = array(
'name' => 'ROWID',
'unique' => TRUE,
'primary' => TRUE,
'columns' => array($column['name']),
);
break;
}
}
}
return array_values($indexes);
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
$keys = array();
foreach ($this->connection->query("PRAGMA foreign_key_list({$this->delimite($table)})") as $row) {
$keys[$row['id']]['name'] = $row['id']; // foreign key name
$keys[$row['id']]['local'] = $row['from']; // local columns
$keys[$row['id']]['table'] = $row['table']; // referenced table
$keys[$row['id']]['foreign'] = $row['to']; // referenced columns
$keys[$row['id']]['onDelete'] = $row['on_delete'];
$keys[$row['id']]['onUpdate'] = $row['on_update'];
if ($keys[$row['id']]['foreign'][0] == NULL) {
$keys[$row['id']]['foreign'] = NULL;
}
}
return array_values($keys);
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
$types = array();
$count = $statement->columnCount();
for ($col = 0; $col < $count; $col++) {
$meta = $statement->getColumnMeta($col);
if (isset($meta['sqlite:decl_type'])) {
if ($meta['sqlite:decl_type'] === 'DATE') {
$types[$meta['name']] = Nette\Database\IReflection::FIELD_UNIX_TIMESTAMP;
} else {
$types[$meta['name']] = Nette\Database\Helpers::detectType($meta['sqlite:decl_type']);
}
} elseif (isset($meta['native_type'])) {
$types[$meta['name']] = Nette\Database\Helpers::detectType($meta['native_type']);
}
}
return $types;
}
/**
* @return bool
*/
public function isSupported($item)
{
return $item === self::SUPPORT_MULTI_INSERT_AS_SELECT || $item === self::SUPPORT_SUBSELECT || $item === self::SUPPORT_MULTI_COLUMN_AS_OR_COND;
}
}
Nette-2.1.0/Nette/Database/Drivers/SqlsrvDriver.php 100777 0 0 15267 12261522617 15327 0 connection = $connection;
}
/********************* SQL ****************d*g**/
/**
* Delimites identifier for use in a SQL statement.
*/
public function delimite($name)
{
/** @see http://msdn.microsoft.com/en-us/library/ms176027.aspx */
return '[' . str_replace(']', ']]', $name) . ']';
}
/**
* Formats boolean for use in a SQL statement.
*/
public function formatBool($value)
{
return $value ? '1' : '0';
}
/**
* Formats date-time for use in a SQL statement.
*/
public function formatDateTime(/*\DateTimeInterface*/ $value)
{
/** @see http://msdn.microsoft.com/en-us/library/ms187819.aspx */
return $value->format("'Y-m-d H:i:s'");
}
/**
* Encodes string for use in a LIKE statement.
*/
public function formatLike($value, $pos)
{
/** @see http://msdn.microsoft.com/en-us/library/ms179859.aspx */
$value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]'));
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
}
/**
* Injects LIMIT/OFFSET to the SQL query.
*/
public function applyLimit(& $sql, $limit, $offset)
{
if ($limit >= 0) {
$sql = preg_replace('#^\s*(SELECT|UPDATE|DELETE)#i', '$0 TOP ' . (int) $limit, $sql, 1, $count);
if (!$count) {
throw new Nette\InvalidArgumentException('SQL query must begin with SELECT, UPDATE or DELETE command.');
}
}
if ($offset > 0) {
throw new Nette\NotSupportedException('Offset is not supported by this database.');
}
}
/**
* Normalizes result row.
*/
public function normalizeRow($row)
{
return $row;
}
/********************* reflection ****************d*g**/
/**
* Returns list of tables.
*/
public function getTables()
{
$tables = array();
foreach ($this->connection->query("
SELECT
name,
CASE type
WHEN 'U' THEN 0
WHEN 'V' THEN 1
END AS [view]
FROM
sys.objects
WHERE
type IN ('U', 'V')
") as $row) {
$tables[] = array(
'name' => $row->name,
'view' => (bool) $row->view,
);
}
return $tables;
}
/**
* Returns metadata for all columns in a table.
*/
public function getColumns($table)
{
$columns = array();
foreach ($this->connection->query("
SELECT
c.name AS name,
o.name AS [table],
UPPER(t.name) AS nativetype,
NULL AS size,
0 AS unsigned,
c.is_nullable AS nullable,
OBJECT_DEFINITION(c.default_object_id) AS [default],
c.is_identity AS autoincrement,
CASE WHEN i.index_id IS NULL
THEN 0
ELSE 1
END AS [primary]
FROM
sys.columns c
JOIN sys.objects o ON c.object_id = o.object_id
LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id
LEFT JOIN sys.key_constraints k ON o.object_id = k.parent_object_id AND k.type = 'PK'
LEFT JOIN sys.index_columns i ON k.parent_object_id = i.object_id AND i.index_id = k.unique_index_id AND i.column_id = c.column_id
WHERE
o.type IN ('U', 'V')
AND o.name = {$this->connection->quote($table)}
") as $row) {
$row = (array) $row;
$row['vendor'] = $row;
$row['unsigned'] = (bool) $row['unsigned'];
$row['nullable'] = (bool) $row['nullable'];
$row['autoincrement'] = (bool) $row['autoincrement'];
$row['primary'] = (bool) $row['primary'];
$columns[] = $row;
}
return $columns;
}
/**
* Returns metadata for all indexes in a table.
*/
public function getIndexes($table)
{
$indexes = array();
foreach ($this->connection->query("
SELECT
i.name AS name,
CASE WHEN i.is_unique = 1 OR i.is_unique_constraint = 1
THEN 1
ELSE 0
END AS [unique],
i.is_primary_key AS [primary],
c.name AS [column]
FROM
sys.indexes i
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
JOIN sys.tables t ON i.object_id = t.object_id
WHERE
t.name = {$this->connection->quote($table)}
ORDER BY
i.index_id,
ic.index_column_id
") as $row) {
$indexes[$row->name]['name'] = $row->name;
$indexes[$row->name]['unique'] = (bool) $row->unique;
$indexes[$row->name]['primary'] = (bool) $row->primary;
$indexes[$row->name]['columns'][] = $row->column;
}
return array_values($indexes);
}
/**
* Returns metadata for all foreign keys in a table.
*/
public function getForeignKeys($table)
{
// Does't work with multicolumn foreign keys
$keys = array();
foreach ($this->connection->query("
SELECT
fk.name AS name,
cl.name AS local,
tf.name AS [table],
cf.name AS [column]
FROM
sys.foreign_keys fk
JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
JOIN sys.tables tl ON fkc.parent_object_id = tl.object_id
JOIN sys.columns cl ON fkc.parent_object_id = cl.object_id AND fkc.parent_column_id = cl.column_id
JOIN sys.tables tf ON fkc.referenced_object_id = tf.object_id
JOIN sys.columns cf ON fkc.referenced_object_id = cf.object_id AND fkc.referenced_column_id = cf.column_id
WHERE
tl.name = {$this->connection->quote($table)}
") as $row) {
$keys[$row->name] = (array) $row;
}
return array_values($keys);
}
/**
* Returns associative array of detected types (IReflection::FIELD_*) in result set.
*/
public function getColumnTypes(\PDOStatement $statement)
{
$types = array();
$count = $statement->columnCount();
for ($col = 0; $col < $count; $col++) {
$meta = $statement->getColumnMeta($col);
if (isset($meta['sqlsrv:decl_type']) && $meta['sqlsrv:decl_type'] !== 'timestamp') { // timestamp does not mean time in sqlsrv
$types[$meta['name']] = Nette\Database\Helpers::detectType($meta['sqlsrv:decl_type']);
} elseif (isset($meta['native_type'])) {
$types[$meta['name']] = Nette\Database\Helpers::detectType($meta['native_type']);
}
}
return $types;
}
/**
* @return bool
*/
public function isSupported($item)
{
return $item === self::SUPPORT_SUBSELECT;
}
}
Nette-2.1.0/Nette/Database/Helpers.php 100777 0 0 16325 12261522617 12641 0 IReflection::FIELD_TEXT, // PostgreSQL arrays
'BYTEA|BLOB|BIN' => IReflection::FIELD_BINARY,
'TEXT|CHAR|POINT|INTERVAL' => IReflection::FIELD_TEXT,
'YEAR|BYTE|COUNTER|SERIAL|INT|LONG|SHORT|^TINY$' => IReflection::FIELD_INTEGER,
'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER' => IReflection::FIELD_FLOAT,
'^TIME$' => IReflection::FIELD_TIME,
'TIME' => IReflection::FIELD_DATETIME, // DATETIME, TIMESTAMP
'DATE' => IReflection::FIELD_DATE,
'BOOL' => IReflection::FIELD_BOOL,
);
/**
* Displays complete result set as HTML table for debug purposes.
* @return void
*/
public static function dumpResult(ResultSet $result)
{
echo "\n\n" . htmlSpecialChars($result->getQueryString()) . "\n";
if (!$result->getColumnCount()) {
echo "\t\n\t\tAffected rows: | \n\t\t", $result->getRowCount(), " | \n\t
\n
\n";
return;
}
$i = 0;
foreach ($result as $row) {
if ($i === 0) {
echo "\n\t\n\t\t#row | \n";
foreach ($row as $col => $foo) {
echo "\t\t" . htmlSpecialChars($col) . " | \n";
}
echo "\t
\n\n\n";
}
echo "\t\n\t\t", $i, " | \n";
foreach ($row as $col) {
//if (is_object($col)) $col = $col->__toString();
echo "\t\t", htmlSpecialChars($col), " | \n";
}
echo "\t
\n";
$i++;
}
if ($i === 0) {
echo "\t\n\t\tempty result set | \n\t
\n\n";
} else {
echo "\n\n";
}
}
/**
* Returns syntax highlighted SQL command.
* @param string
* @return string
*/
public static function dumpSql($sql, array $params = NULL)
{
static $keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|[RI]?LIKE|REGEXP|TRUE|FALSE';
// insert new lines
$sql = " $sql ";
$sql = preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i", "\n\$1", $sql);
// reduce spaces
$sql = preg_replace('#[ \t]{2,}#', " ", $sql);
$sql = wordwrap($sql, 100);
$sql = preg_replace('#([ \t]*\r?\n){2,}#', "\n", $sql);
// syntax highlight
$sql = htmlSpecialChars($sql);
$sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is", function($matches) {
if (!empty($matches[1])) { // comment
return '' . $matches[1] . '';
} elseif (!empty($matches[2])) { // error
return '' . $matches[2] . '';
} elseif (!empty($matches[3])) { // most important keywords
return '' . $matches[3] . '';
} elseif (!empty($matches[4])) { // other keywords
return '' . $matches[4] . '';
}
}, $sql);
// parameters
$sql = preg_replace_callback('#\?#', function() use ($params) {
static $i = 0;
if (!isset($params[$i])) {
return '?';
}
$param = $params[$i++];
if (is_string($param) && (preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u', $param) || preg_last_error())) {
return '<binary>';
} elseif (is_string($param)) {
return '\'' . htmlspecialchars(Nette\Utils\Strings::truncate($param, Helpers::$maxLength)) . "'";
} elseif (is_resource($param)) {
$type = get_resource_type($param);
if ($type === 'stream') {
$info = stream_get_meta_data($param);
}
return '<' . htmlSpecialChars($type) . " resource> ";
} else {
return htmlspecialchars($param);
}
}, $sql);
return '' . trim($sql) . "
\n";
}
/**
* Common column type detection.
* @return array
*/
public static function detectTypes(\PDOStatement $statement)
{
$types = array();
$count = $statement->columnCount(); // driver must be meta-aware, see PHP bugs #53782, #54695
for ($col = 0; $col < $count; $col++) {
$meta = $statement->getColumnMeta($col);
if (isset($meta['native_type'])) {
$types[$meta['name']] = self::detectType($meta['native_type']);
}
}
return $types;
}
/**
* Heuristic column type detection.
* @param string
* @return string
* @internal
*/
public static function detectType($type)
{
static $cache;
if (!isset($cache[$type])) {
$cache[$type] = 'string';
foreach (self::$typePatterns as $s => $val) {
if (preg_match("#$s#i", $type)) {
return $cache[$type] = $val;
}
}
}
return $cache[$type];
}
/**
* Import SQL dump from file - extreme fast.
* @return int count of commands
*/
public static function loadFromFile(Connection $connection, $file)
{
@set_time_limit(0); // intentionally @
$handle = @fopen($file, 'r'); // intentionally @
if (!$handle) {
throw new Nette\FileNotFoundException("Cannot open file '$file'.");
}
$count = 0;
$sql = '';
while (!feof($handle)) {
$s = fgets($handle);
$sql .= $s;
if (substr(rtrim($s), -1) === ';') {
$connection->query($sql); // native query without logging
$sql = '';
$count++;
}
}
if (trim($sql) !== '') {
$connection->query($sql);
$count++;
}
fclose($handle);
return $count;
}
public static function createDebugPanel($connection, $explain = TRUE, $name = NULL)
{
$panel = new Nette\Database\Diagnostics\ConnectionPanel($connection);
$panel->explain = $explain;
$panel->name = $name;
Nette\Diagnostics\Debugger::getBar()->addPanel($panel);
return $panel;
}
/**
* Reformat source to key -> value pairs.
* @return array
*/
public static function toPairs(array $rows, $key = NULL, $value = NULL)
{
if (!$rows) {
return array();
}
$keys = array_keys((array) reset($rows));
if (!count($keys)) {
throw new \LogicException('Result set does not contain any column.');
} elseif ($key === NULL && $value === NULL) {
if (count($keys) === 1) {
list($value) = $keys;
} else {
list($key, $value) = $keys;
}
}
$return = array();
if ($key === NULL) {
foreach ($rows as $row) {
$return[] = ($value === NULL ? $row : $row[$value]);
}
} else {
foreach ($rows as $row) {
$return[is_object($row[$key]) ? (string) $row[$key] : $row[$key]] = ($value === NULL ? $row : $row[$value]);
}
}
return $return;
}
}
Nette-2.1.0/Nette/Database/IReflection.php 100777 0 0 3023 12261522617 13411 0 , %2$s for table name
* @param string %1$s stands for key used after ->, %2$s for table name
*/
public function __construct($primary = 'id', $foreign = '%s_id', $table = '%s')
{
$this->primary = $primary;
$this->foreign = $foreign;
$this->table = $table;
}
public function getPrimary($table)
{
return sprintf($this->primary, $this->getColumnFromTable($table));
}
public function getHasManyReference($table, $key)
{
$table = $this->getColumnFromTable($table);
return array(
sprintf($this->table, $key, $table),
sprintf($this->foreign, $table, $key),
);
}
public function getBelongsToReference($table, $key)
{
$table = $this->getColumnFromTable($table);
return array(
sprintf($this->table, $key, $table),
sprintf($this->foreign, $key, $table),
);
}
protected function getColumnFromTable($name)
{
if ($this->table !== '%s' && preg_match('(^' . str_replace('%s', '(.*)', preg_quote($this->table)) . '\z)', $name, $match)) {
return $match[1];
}
return $name;
}
}
Nette-2.1.0/Nette/Database/Reflection/DiscoveredReflection.php 100777 0 0 11127 12261522617 17426 0 connection = $connection;
if ($cacheStorage) {
$this->cache = new Nette\Caching\Cache($cacheStorage, 'Nette.Database.' . md5($connection->getDsn()));
$this->structure = $this->loadedStructure = $this->cache->load('structure') ?: array();
}
}
public function __destruct()
{
if ($this->cache && $this->structure !== $this->loadedStructure) {
$this->cache->save('structure', $this->structure);
}
}
public function getPrimary($table)
{
$primary = & $this->structure['primary'][strtolower($table)];
if (isset($primary)) {
return empty($primary) ? NULL : $primary;
}
$columns = $this->connection->getSupplementalDriver()->getColumns($table);
$primary = array();
foreach ($columns as $column) {
if ($column['primary']) {
$primary[] = $column['name'];
}
}
if (count($primary) === 0) {
return NULL;
} elseif (count($primary) === 1) {
$primary = reset($primary);
}
return $primary;
}
public function getHasManyReference($table, $key, $refresh = TRUE)
{
if (isset($this->structure['hasMany'][strtolower($table)])) {
$candidates = $columnCandidates = array();
foreach ($this->structure['hasMany'][strtolower($table)] as $targetPair) {
list($targetColumn, $targetTable) = $targetPair;
if (stripos($targetTable, $key) === FALSE) {
continue;
}
$candidates[] = array($targetTable, $targetColumn);
if (stripos($targetColumn, $table) !== FALSE) {
$columnCandidates[] = $candidate = array($targetTable, $targetColumn);
if (strtolower($targetTable) === strtolower($key)) {
return $candidate;
}
}
}
if (count($columnCandidates) === 1) {
return reset($columnCandidates);
} elseif (count($candidates) === 1) {
return reset($candidates);
}
foreach ($candidates as $candidate) {
if (strtolower($candidate[0]) === strtolower($key)) {
return $candidate;
}
}
}
if ($refresh) {
$this->reloadAllForeignKeys();
return $this->getHasManyReference($table, $key, FALSE);
}
if (empty($candidates)) {
throw new MissingReferenceException("No reference found for \${$table}->related({$key}).");
} else {
throw new AmbiguousReferenceKeyException('Ambiguous joining column in related call.');
}
}
public function getBelongsToReference($table, $key, $refresh = TRUE)
{
if (isset($this->structure['belongsTo'][strtolower($table)])) {
foreach ($this->structure['belongsTo'][strtolower($table)] as $column => $targetTable) {
if (stripos($column, $key) !== FALSE) {
return array($targetTable, $column);
}
}
}
if ($refresh) {
$this->reloadForeignKeys($table);
return $this->getBelongsToReference($table, $key, FALSE);
}
throw new MissingReferenceException("No reference found for \${$table}->{$key}.");
}
protected function reloadAllForeignKeys()
{
$this->structure['hasMany'] = $this->structure['belongsTo'] = array();
foreach ($this->connection->getSupplementalDriver()->getTables() as $table) {
if ($table['view'] == FALSE) {
$this->reloadForeignKeys($table['name']);
}
}
foreach ($this->structure['hasMany'] as & $table) {
uksort($table, function($a, $b) {
return strlen($a) - strlen($b);
});
}
}
protected function reloadForeignKeys($table)
{
foreach ($this->connection->getSupplementalDriver()->getForeignKeys($table) as $row) {
$this->structure['belongsTo'][strtolower($table)][$row['local']] = $row['table'];
$this->structure['hasMany'][strtolower($row['table'])][$row['local'] . $table] = array($row['local'], $table);
}
if (isset($this->structure['belongsTo'][$table])) {
uksort($this->structure['belongsTo'][$table], function($a, $b) {
return strlen($a) - strlen($b);
});
}
}
}
Nette-2.1.0/Nette/Database/Reflection/exceptions.php 100777 0 0 656 12261522617 15452 0 connection = $connection;
$this->supplementalDriver = $connection->getSupplementalDriver();
$this->queryString = $queryString;
$this->params = $params;
if (substr($queryString, 0, 2) === '::') {
$connection->getPdo()->{substr($queryString, 2)}();
} elseif ($queryString !== NULL) {
$this->pdoStatement = $connection->getPdo()->prepare($queryString);
$this->pdoStatement->setFetchMode(PDO::FETCH_ASSOC);
$this->pdoStatement->execute($params);
}
$this->time = microtime(TRUE) - $time;
}
/**
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* @internal
* @return \PDOStatement
*/
public function getPdoStatement()
{
return $this->pdoStatement;
}
/**
* @return string
*/
public function getQueryString()
{
return $this->queryString;
}
/**
* @return array
*/
public function getParameters()
{
return $this->params;
}
/**
* @return int
*/
public function getColumnCount()
{
return $this->pdoStatement ? $this->pdoStatement->columnCount() : NULL;
}
/**
* @return int
*/
public function getRowCount()
{
return $this->pdoStatement ? $this->pdoStatement->rowCount() : NULL;
}
/**
* @return float
*/
public function getTime()
{
return $this->time;
}
/**
* Normalizes result row.
* @param array
* @return array
*/
public function normalizeRow($row)
{
if ($this->types === NULL) {
$this->types = (array) $this->supplementalDriver->getColumnTypes($this->pdoStatement);
}
foreach ($this->types as $key => $type) {
$value = $row[$key];
if ($value === NULL || $value === FALSE || $type === IReflection::FIELD_TEXT) {
} elseif ($type === IReflection::FIELD_INTEGER) {
$row[$key] = is_float($tmp = $value * 1) ? $value : $tmp;
} elseif ($type === IReflection::FIELD_FLOAT) {
if (($pos = strpos($value, '.')) !== FALSE) {
$value = rtrim(rtrim($pos === 0 ? "0$value" : $value, '0'), '.');
}
$float = (float) $value;
$row[$key] = (string) $float === $value ? $float : $value;
} elseif ($type === IReflection::FIELD_BOOL) {
$row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F';
} elseif ($type === IReflection::FIELD_DATETIME || $type === IReflection::FIELD_DATE || $type === IReflection::FIELD_TIME) {
$row[$key] = new Nette\DateTime($value);
} elseif ($type === IReflection::FIELD_TIME_INTERVAL) {
preg_match('#^(-?)(\d+)\D(\d+)\D(\d+)\z#', $value, $m);
$row[$key] = new \DateInterval("PT$m[2]H$m[3]M$m[4]S");
$row[$key]->invert = (int) (bool) $m[1];
} elseif ($type === IReflection::FIELD_UNIX_TIMESTAMP) {
$row[$key] = Nette\DateTime::from($value);
}
}
return $this->supplementalDriver->normalizeRow($row);
}
/********************* misc tools ****************d*g**/
/**
* Displays complete result set as HTML table for debug purposes.
* @return void
*/
public function dump()
{
Helpers::dumpResult($this);
}
/********************* interface Iterator ****************d*g**/
public function rewind()
{
if ($this->result === FALSE) {
throw new Nette\InvalidStateException('Nette\\Database\\ResultSet implements only one way iterator.');
}
}
public function current()
{
return $this->result;
}
public function key()
{
return $this->resultKey;
}
public function next()
{
$this->result = FALSE;
}
public function valid()
{
if ($this->result) {
return TRUE;
}
return $this->fetch() !== FALSE;
}
/********************* interface IRowContainer ****************d*g**/
/**
* @inheritDoc
*/
public function fetch()
{
$data = $this->pdoStatement ? $this->pdoStatement->fetch() : NULL;
if (!$data) {
$this->pdoStatement->closeCursor();
return FALSE;
}
$row = new Row;
foreach ($this->normalizeRow($data) as $key => $value) {
$row->$key = $value;
}
if ($this->result === NULL && count($data) !== $this->pdoStatement->columnCount()) {
trigger_error('Found duplicate columns in database result set.', E_USER_NOTICE);
}
$this->resultKey++;
return $this->result = $row;
}
/**
* Fetches single field.
* @return mixed|FALSE
*/
public function fetchField($column = 0)
{
$row = $this->fetch();
return $row ? $row[$column] : FALSE;
}
/**
* @inheritDoc
*/
public function fetchPairs($key = NULL, $value = NULL)
{
return Helpers::toPairs($this->fetchAll(), $key, $value);
}
/**
* @inheritDoc
*/
public function fetchAll()
{
if ($this->results === NULL) {
$this->results = iterator_to_array($this);
}
return $this->results;
}
/** @deprecated */
function columnCount()
{
trigger_error(__METHOD__ . '() is deprecated; use getColumnCount() instead.', E_USER_DEPRECATED);
return $this->getColumnCount();
}
/** @deprecated */
function rowCount()
{
trigger_error(__METHOD__ . '() is deprecated; use getRowCount() instead.', E_USER_DEPRECATED);
return $this->getRowCount();
}
}
Nette-2.1.0/Nette/Database/Row.php 100777 0 0 1724 12261522617 11763 0 $key;
}
/**
* Checks if $key exists.
* @param mixed key or index
* @return bool
*/
public function offsetExists($key)
{
if (is_int($key)) {
return (bool) current(array_slice((array) $this, $key, 1));
}
return parent::offsetExists($key);
}
}
Nette-2.1.0/Nette/Database/SqlLiteral.php 100777 0 0 1400 12261522617 13257 0 value = (string) $value;
$this->parameters = $parameters;
}
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* @return string
*/
public function __toString()
{
return $this->value;
}
}
Nette-2.1.0/Nette/Database/SqlPreprocessor.php 100777 0 0 14151 12261522617 14400 0 connection = $connection;
$this->driver = $connection->getSupplementalDriver();
$this->arrayModes = array(
'INSERT' => $this->driver->isSupported(ISupplementalDriver::SUPPORT_MULTI_INSERT_AS_SELECT) ? 'select' : 'values',
'REPLACE' => 'values',
'UPDATE' => 'assoc',
'WHERE' => 'and',
'HAVING' => 'and',
'ORDER BY' => 'order',
'GROUP BY' => 'order',
);
}
/**
* @param array
* @return array of [sql, params]
*/
public function process($params)
{
$this->params = $params;
$this->counter = 0;
$this->remaining = array();
$this->arrayMode = 'assoc';
$res = array();
while ($this->counter < count($params)) {
$param = $params[$this->counter++];
if (($this->counter === 2 && count($params) === 2) || !is_scalar($param)) {
$res[] = $this->formatValue($param);
} else {
$res[] = Nette\Utils\Strings::replace(
$param,
'~\'.*?\'|".*?"|\?|\b(?:INSERT|REPLACE|UPDATE|WHERE|HAVING|ORDER BY|GROUP BY)\b|/\*.*?\*/|--[^\n]*~si',
array($this, 'callback')
);
}
}
return array(implode(' ', $res), $this->remaining);
}
/** @internal */
public function callback($m)
{
$m = $m[0];
if ($m[0] === "'" || $m[0] === '"' || $m[0] === '/' || $m[0] === '-') { // string or comment
return $m;
} elseif ($m === '?') { // placeholder
if ($this->counter >= count($this->params)) {
throw new Nette\InvalidArgumentException('There are more placeholders than passed parameters.');
}
return $this->formatValue($this->params[$this->counter++]);
} else { // command
$this->arrayMode = $this->arrayModes[strtoupper($m)];
return $m;
}
}
private function formatValue($value)
{
if (is_string($value)) {
if (strlen($value) > 20) {
$this->remaining[] = $value;
return '?';
} else {
return $this->connection->quote($value);
}
} elseif (is_int($value)) {
return (string) $value;
} elseif (is_float($value)) {
return rtrim(rtrim(number_format($value, 10, '.', ''), '0'), '.');
} elseif (is_bool($value)) {
return $this->driver->formatBool($value);
} elseif ($value === NULL) {
return 'NULL';
} elseif ($value instanceof Table\IRow) {
return $value->getPrimary();
} elseif (is_array($value) || $value instanceof \Traversable) {
$vx = $kx = array();
if ($value instanceof \Traversable) {
$value = iterator_to_array($value);
}
if (isset($value[0])) { // non-associative; value, value, value
foreach ($value as $v) {
if (is_array($v) && isset($v[0])) { // no-associative; (value), (value), (value)
$vx[] = '(' . $this->formatValue($v) . ')';
} else {
$vx[] = $this->formatValue($v);
}
}
if ($this->arrayMode === 'union') {
return implode(' ', $vx);
}
return implode(', ', $vx);
} elseif ($this->arrayMode === 'values') { // (key, key, ...) VALUES (value, value, ...)
$this->arrayMode = 'multi';
foreach ($value as $k => $v) {
$kx[] = $this->driver->delimite($k);
$vx[] = $this->formatValue($v);
}
return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
} elseif ($this->arrayMode === 'select') { // (key, key, ...) SELECT value, value, ...
$this->arrayMode = 'union';
foreach ($value as $k => $v) {
$kx[] = $this->driver->delimite($k);
$vx[] = $this->formatValue($v);
}
return '(' . implode(', ', $kx) . ') SELECT ' . implode(', ', $vx);
} elseif ($this->arrayMode === 'assoc') { // key=value, key=value, ...
foreach ($value as $k => $v) {
if (substr($k, -1) === '=') {
$k2 = $this->driver->delimite(substr($k, 0, -2));
$vx[] = $k2 . '=' . $k2 . ' ' . substr($k, -2, 1) . ' ' . $this->formatValue($v);
} else {
$vx[] = $this->driver->delimite($k) . '=' . $this->formatValue($v);
}
}
return implode(', ', $vx);
} elseif ($this->arrayMode === 'multi') { // multiple insert (value, value, ...), ...
foreach ($value as $v) {
$vx[] = $this->formatValue($v);
}
return '(' . implode(', ', $vx) . ')';
} elseif ($this->arrayMode === 'union') { // UNION ALL SELECT value, value, ...
foreach ($value as $v) {
$vx[] = $this->formatValue($v);
}
return 'UNION ALL SELECT ' . implode(', ', $vx);
} elseif ($this->arrayMode === 'and') { // (key [operator] value) AND ...
foreach ($value as $k => $v) {
$k = $this->driver->delimite($k);
if (is_array($v)) {
$vx[] = $v ? ($k . ' IN (' . $this->formatValue(array_values($v)) . ')') : '1=0';
} else {
$v = $this->formatValue($v);
$vx[] = $k . ($v === 'NULL' ? ' IS ' : ' = ') . $v;
}
}
return $value ? '(' . implode(') AND (', $vx) . ')' : '1=1';
} elseif ($this->arrayMode === 'order') { // key, key DESC, ...
foreach ($value as $k => $v) {
$vx[] = $this->driver->delimite($k) . ($v > 0 ? '' : ' DESC');
}
return implode(', ', $vx);
}
} elseif ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
return $this->driver->formatDateTime($value);
} elseif ($value instanceof SqlLiteral) {
$this->remaining = array_merge($this->remaining, $value->getParameters());
return $value->__toString();
} else {
$this->remaining[] = $value;
return '?';
}
}
}
Nette-2.1.0/Nette/Database/Table/ 40777 0 0 0 12261522617 11426 5 Nette-2.1.0/Nette/Database/Table/ActiveRow.php 100777 0 0 16142 12261522617 14166 0 data = $data;
$this->table = $table;
}
/**
* @internal
* @ignore
*/
public function setTable(Selection $table)
{
$this->table = $table;
}
/**
* @internal
*/
public function getTable()
{
return $this->table;
}
public function __toString()
{
try {
return (string) $this->getPrimary();
} catch (\Exception $e) {
trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
}
}
/**
* @return array
*/
public function toArray()
{
$this->accessColumn(NULL);
return $this->data;
}
/**
* Returns primary key value.
* @param bool
* @return mixed possible int, string, array, object (Nette\DateTime)
*/
public function getPrimary($need = TRUE)
{
$primary = $this->table->getPrimary($need);
if ($primary === NULL) {
return NULL;
} elseif (!is_array($primary)) {
if (isset($this->data[$primary])) {
return $this->data[$primary];
} elseif ($need) {
throw new Nette\InvalidStateException("Row does not contain primary $primary column data.");
} else {
return NULL;
}
} else {
$primaryVal = array();
foreach ($primary as $key) {
if (!isset($this->data[$key])) {
if ($need) {
throw new Nette\InvalidStateException("Row does not contain primary $key column data.");
} else {
return NULL;
}
}
$primaryVal[$key] = $this->data[$key];
}
return $primaryVal;
}
}
/**
* Returns row signature (composition of primary keys)
* @param bool
* @return string
*/
public function getSignature($need = TRUE)
{
return implode('|', (array) $this->getPrimary($need));
}
/**
* Returns referenced row.
* @param string
* @param string
* @return IRow or NULL if the row does not exist
*/
public function ref($key, $throughColumn = NULL)
{
if (!$throughColumn) {
list($key, $throughColumn) = $this->table->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
}
return $this->getReference($key, $throughColumn);
}
/**
* Returns referencing rows.
* @param string
* @param string
* @return GroupedSelection
*/
public function related($key, $throughColumn = NULL)
{
if (strpos($key, '.') !== FALSE) {
list($key, $throughColumn) = explode('.', $key);
} elseif (!$throughColumn) {
list($key, $throughColumn) = $this->table->getDatabaseReflection()->getHasManyReference($this->table->getName(), $key);
}
return $this->table->getReferencingTable($key, $throughColumn, $this[$this->table->getPrimary()]);
}
/**
* Updates row.
* @param array|\Traversable (column => value)
* @return bool
*/
public function update($data)
{
$selection = $this->table->createSelectionInstance()
->wherePrimary($this->getPrimary());
if ($selection->update($data)) {
$this->isModified = TRUE;
$selection->select('*');
if (($row = $selection->fetch()) === FALSE) {
throw new Nette\InvalidStateException('Database refetch failed; row does not exist!');
}
$this->data = $row->data;
return TRUE;
} else {
return FALSE;
}
}
/**
* Deletes row.
* @return int number of affected rows
*/
public function delete()
{
$res = $this->table->createSelectionInstance()
->wherePrimary($this->getPrimary())
->delete();
if ($res > 0 && ($signature = $this->getSignature(FALSE))) {
unset($this->table[$signature]);
}
return $res;
}
/********************* interface IteratorAggregate ****************d*g**/
public function getIterator()
{
$this->accessColumn(NULL);
return new \ArrayIterator($this->data);
}
/********************* interface ArrayAccess & magic accessors ****************d*g**/
/**
* Stores value in column.
* @param string column name
* @param string value
* @return void
*/
public function offsetSet($key, $value)
{
$this->__set($key, $value);
}
/**
* Returns value of column.
* @param string column name
* @return string
*/
public function offsetGet($key)
{
return $this->__get($key);
}
/**
* Tests if column exists.
* @param string column name
* @return bool
*/
public function offsetExists($key)
{
return $this->__isset($key);
}
/**
* Removes column from data.
* @param string column name
* @return void
*/
public function offsetUnset($key)
{
$this->__unset($key);
}
public function __set($key, $value)
{
throw new Nette\DeprecatedException('ActiveRow is read-only; use update() method instead.');
}
public function &__get($key)
{
$this->accessColumn($key);
if (array_key_exists($key, $this->data)) {
return $this->data[$key];
}
try {
list($table, $column) = $this->table->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
$referenced = $this->getReference($table, $column);
if ($referenced !== FALSE) {
$this->accessColumn($key, FALSE);
return $referenced;
}
} catch(MissingReferenceException $e) {}
$this->removeAccessColumn($key);
throw new Nette\MemberAccessException("Cannot read an undeclared column \"$key\".");
}
public function __isset($key)
{
$this->accessColumn($key);
if (array_key_exists($key, $this->data)) {
return isset($this->data[$key]);
}
$this->removeAccessColumn($key);
return FALSE;
}
public function __unset($key)
{
throw new Nette\DeprecatedException('ActiveRow is read-only.');
}
protected function accessColumn($key, $selectColumn = TRUE)
{
$this->table->accessColumn($key, $selectColumn);
if ($this->table->getDataRefreshed() && !$this->dataRefreshed) {
$this->data = $this->table[$this->getSignature()]->data;
$this->dataRefreshed = TRUE;
}
}
protected function removeAccessColumn($key)
{
$this->table->removeAccessColumn($key);
}
protected function getReference($table, $column)
{
$this->accessColumn($column);
if (array_key_exists($column, $this->data)) {
$value = $this->data[$column];
$referenced = $this->table->getReferencedTable($table, $column, $value);
return isset($referenced[$value]) ? $referenced[$value] : NULL; // referenced row may not exist
}
return FALSE;
}
}
Nette-2.1.0/Nette/Database/Table/GroupedSelection.php 100777 0 0 14777 12261522617 15552 0 refTable = $refTable;
$this->column = $column;
parent::__construct($refTable->connection, $table, $refTable->reflection, $refTable->cache ? $refTable->cache->getStorage() : NULL);
}
/**
* Sets active group.
* @internal
* @param int primary key of grouped rows
* @return GroupedSelection
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/** @deprecated */
public function through($column)
{
trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::related("' . $this->name . '", "' . $column . '") instead.', E_USER_DEPRECATED);
$this->column = $column;
$this->delimitedColumn = $this->refTable->connection->getSupplementalDriver()->delimite($this->column);
return $this;
}
public function select($columns)
{
if (!$this->sqlBuilder->getSelect()) {
$this->sqlBuilder->addSelect("$this->name.$this->column");
}
return call_user_func_array('parent::select', func_get_args());
}
public function order($columns)
{
if (!$this->sqlBuilder->getOrder()) {
// improve index utilization
$this->sqlBuilder->addOrder("$this->name.$this->column" . (preg_match('~\bDESC\z~i', $columns) ? ' DESC' : ''));
}
return call_user_func_array('parent::order', func_get_args());
}
/********************* aggregations ****************d*g**/
public function aggregation($function)
{
$aggregation = & $this->getRefTable($refPath)->aggregation[$refPath . $function . $this->getSql() . json_encode($this->sqlBuilder->getParameters())];
if ($aggregation === NULL) {
$aggregation = array();
$selection = $this->createSelectionInstance();
$selection->getSqlBuilder()->importConditions($this->getSqlBuilder());
$selection->select($function);
$selection->select("$this->name.$this->column");
$selection->group("$this->name.$this->column");
foreach ($selection as $row) {
$aggregation[$row[$this->column]] = $row;
}
}
if (isset($aggregation[$this->active])) {
foreach ($aggregation[$this->active] as $val) {
return $val;
}
}
}
public function count($column = NULL)
{
$return = parent::count($column);
return isset($return) ? $return : 0;
}
/********************* internal ****************d*g**/
protected function execute()
{
if ($this->rows !== NULL) {
$this->observeCache = $this;
return;
}
$accessedColumns = $this->accessedColumns;
$this->loadRefCache();
if (!isset($this->refCacheCurrent['data'])) {
// we have not fetched any data yet => init accessedColumns by cached accessedColumns
$this->accessedColumns = $accessedColumns;
$limit = $this->sqlBuilder->getLimit();
$rows = count($this->refTable->rows);
if ($limit && $rows > 1) {
$this->sqlBuilder->setLimit(NULL, NULL);
}
parent::execute();
$this->sqlBuilder->setLimit($limit, NULL);
$data = array();
$offset = array();
$this->accessColumn($this->column);
foreach ((array) $this->rows as $key => $row) {
$ref = & $data[$row[$this->column]];
$skip = & $offset[$row[$this->column]];
if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->sqlBuilder->getOffset())) {
$ref[$key] = $row;
} else {
unset($this->rows[$key]);
}
$skip++;
unset($ref, $skip);
}
$this->refCacheCurrent['data'] = $data;
$this->data = & $this->refCacheCurrent['data'][$this->active];
}
$this->observeCache = $this;
if ($this->data === NULL) {
$this->data = array();
} else {
foreach ($this->data as $row) {
$row->setTable($this); // injects correct parent GroupedSelection
}
reset($this->data);
}
}
protected function getRefTable(& $refPath)
{
$refObj = $this->refTable;
$refPath = $this->name . '.';
while ($refObj instanceof GroupedSelection) {
$refPath .= $refObj->name . '.';
$refObj = $refObj->refTable;
}
return $refObj;
}
protected function loadRefCache()
{
$hash = $this->getSpecificCacheKey();
$referencing = & $this->refCache['referencing'][$this->getGeneralCacheKey()];
$this->observeCache = & $referencing['observeCache'];
$this->refCacheCurrent = & $referencing[$hash];
$this->accessedColumns = & $referencing[$hash]['accessed'];
$this->specificCacheKey = & $referencing[$hash]['specificCacheKey'];
$this->rows = & $referencing[$hash]['rows'];
if (isset($referencing[$hash]['data'][$this->active])) {
$this->data = & $referencing[$hash]['data'][$this->active];
}
}
/********************* manipulation ****************d*g**/
public function insert($data)
{
if ($data instanceof \Traversable && !$data instanceof Selection) {
$data = iterator_to_array($data);
}
if (Nette\Utils\Arrays::isList($data)) {
foreach (array_keys($data) as $key) {
$data[$key][$this->column] = $this->active;
}
} else {
$data[$this->column] = $this->active;
}
return parent::insert($data);
}
public function update($data)
{
$builder = $this->sqlBuilder;
$this->sqlBuilder = clone $this->sqlBuilder;
$this->where($this->column, $this->active);
$return = parent::update($data);
$this->sqlBuilder = $builder;
return $return;
}
public function delete()
{
$builder = $this->sqlBuilder;
$this->sqlBuilder = clone $this->sqlBuilder;
$this->where($this->column, $this->active);
$return = parent::delete();
$this->sqlBuilder = $builder;
return $return;
}
}
Nette-2.1.0/Nette/Database/Table/IRow.php 100777 0 0 1052 12261522617 13115 0 IRow] format */
protected $rows;
/** @var IRow[] modifiable data in [primary key => IRow] format */
protected $data;
/** @var bool */
protected $dataRefreshed = FALSE;
/** @var mixed cache array of Selection and GroupedSelection prototypes */
protected $globalRefCache;
/** @var mixed */
protected $refCache;
/** @var string */
protected $generalCacheKey;
/** @var string */
protected $specificCacheKey;
/** @var array of [conditions => [key => IRow]]; used by GroupedSelection */
protected $aggregation = array();
/** @var array of touched columns */
protected $accessedColumns;
/** @var array of earlier touched columns */
protected $previousAccessedColumns;
/** @var bool should instance observe accessed columns caching */
protected $observeCache = FALSE;
/** @var array of primary key values */
protected $keys = array();
/**
* Creates filtered table representation.
* @param Nette\Database\Connection
* @param string database table name
*/
public function __construct(Nette\Database\Connection $connection, $table, Nette\Database\IReflection $reflection, Nette\Caching\IStorage $cacheStorage = NULL)
{
$this->name = $table;
$this->connection = $connection;
$this->reflection = $reflection;
$this->cache = $cacheStorage ? new Nette\Caching\Cache($cacheStorage, 'Nette.Database.' . md5($connection->getDsn())) : NULL;
$this->primary = $reflection->getPrimary($table);
$this->sqlBuilder = new SqlBuilder($table, $connection, $reflection);
$this->refCache = & $this->getRefTable($refPath)->globalRefCache[$refPath];
}
public function __destruct()
{
$this->saveCacheState();
}
public function __clone()
{
$this->sqlBuilder = clone $this->sqlBuilder;
}
/**
* @return Nette\Database\Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* @return Nette\Database\IReflection
*/
public function getDatabaseReflection()
{
return $this->reflection;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param bool
* @return string|array
*/
public function getPrimary($need = TRUE)
{
if ($this->primary === NULL && $need) {
throw new \LogicException("Table \"{$this->name}\" does not have a primary key.");
}
return $this->primary;
}
/**
* @return string
*/
public function getPrimarySequence()
{
if ($this->primarySequence === FALSE) {
$this->primarySequence = NULL;
$driver = $this->connection->getSupplementalDriver();
if ($driver->isSupported(ISupplementalDriver::SUPPORT_SEQUENCE) && $this->primary !== NULL) {
foreach ($driver->getColumns($this->name) as $column) {
if ($column['name'] === $this->primary) {
$this->primarySequence = $column['vendor']['sequence'];
break;
}
}
}
}
return $this->primarySequence;
}
/**
* @param string
* @return self
*/
public function setPrimarySequence($sequence)
{
$this->primarySequence = $sequence;
return $this;
}
/**
* @return string
*/
public function getSql()
{
return $this->sqlBuilder->buildSelectQuery($this->getPreviousAccessedColumns());
}
/**
* Loads cache of previous accessed columns and returns it.
* @internal
* @return array|false
*/
public function getPreviousAccessedColumns()
{
if ($this->cache && $this->previousAccessedColumns === NULL) {
$this->accessedColumns = $this->previousAccessedColumns = $this->cache->load($this->getGeneralCacheKey());
if ($this->previousAccessedColumns === NULL) {
$this->previousAccessedColumns = array();
}
}
return array_keys(array_filter((array) $this->previousAccessedColumns));
}
/**
* @internal
* @return SqlBuilder
*/
public function getSqlBuilder()
{
return $this->sqlBuilder;
}
/********************* quick access ****************d*g**/
/**
* Returns row specified by primary key.
* @param mixed primary key
* @return IRow or FALSE if there is no such row
*/
public function get($key)
{
$clone = clone $this;
return $clone->wherePrimary($key)->fetch();
}
/**
* @inheritDoc
*/
public function fetch()
{
$this->execute();
$return = current($this->data);
next($this->data);
return $return;
}
/**
* @inheritDoc
*/
public function fetchPairs($key = NULL, $value = NULL)
{
return Nette\Database\Helpers::toPairs(iterator_to_array($this), $key, $value);
}
/**
* @inheritDoc
*/
public function fetchAll()
{
return iterator_to_array($this);
}
/********************* sql selectors ****************d*g**/
/**
* Adds select clause, more calls appends to the end.
* @param string for example "column, MD5(column) AS column_md5"
* @return self
*/
public function select($columns)
{
$this->emptyResultSet();
call_user_func_array(array($this->sqlBuilder, 'addSelect'), func_get_args());
return $this;
}
/**
* @deprecated
*/
public function find($key)
{
trigger_error(__METHOD__ . '() is deprecated; use $selection->wherePrimary() instead.', E_USER_DEPRECATED);
return $this->wherePrimary($key);
}
/**
* Adds condition for primary key.
* @param mixed
* @return self
*/
public function wherePrimary($key)
{
if (is_array($this->primary) && Nette\Utils\Arrays::isList($key)) {
if (isset($key[0]) && is_array($key[0])) {
$this->where($this->primary, $key);
} else {
foreach ($this->primary as $i => $primary) {
$this->where($this->name . '.' . $primary, $key[$i]);
}
}
} elseif (is_array($key) && !Nette\Utils\Arrays::isList($key)) { // key contains column names
$this->where($key);
} else {
$this->where($this->name . '.' . $this->getPrimary(), $key);
}
return $this;
}
/**
* Adds where condition, more calls appends with AND.
* @param string condition possibly containing ?
* @param mixed
* @param mixed ...
* @return self
*/
public function where($condition, $parameters = array())
{
if (is_array($condition) && $parameters === array()) { // where(array('column1' => 1, 'column2 > ?' => 2))
foreach ($condition as $key => $val) {
if (is_int($key)) {
$this->where($val); // where('full condition')
} else {
$this->where($key, $val); // where('column', 1)
}
}
return $this;
}
$this->emptyResultSet();
call_user_func_array(array($this->sqlBuilder, 'addWhere'), func_get_args());
return $this;
}
/**
* Adds order clause, more calls appends to the end.
* @param string for example 'column1, column2 DESC'
* @return self
*/
public function order($columns)
{
$this->emptyResultSet();
call_user_func_array(array($this->sqlBuilder, 'addOrder'), func_get_args());
return $this;
}
/**
* Sets limit clause, more calls rewrite old values.
* @param int
* @param int
* @return self
*/
public function limit($limit, $offset = NULL)
{
$this->emptyResultSet();
$this->sqlBuilder->setLimit($limit, $offset);
return $this;
}
/**
* Sets offset using page number, more calls rewrite old values.
* @param int
* @param int
* @return self
*/
public function page($page, $itemsPerPage, & $numOfPages = NULL)
{
if (func_get_args() > 2) {
$numOfPages = (int) ceil($this->count('*') / $itemsPerPage);
}
return $this->limit($itemsPerPage, ($page - 1) * $itemsPerPage);
}
/**
* Sets group clause, more calls rewrite old value.
* @param string
* @return self
*/
public function group($columns)
{
$this->emptyResultSet();
if (func_num_args() === 2 && strpos($columns, '?') === FALSE) {
trigger_error('Calling ' . __METHOD__ . '() with second argument is deprecated; use $selection->having() instead.', E_USER_DEPRECATED);
$this->having(func_get_arg(1));
$this->sqlBuilder->setGroup($columns);
} else {
call_user_func_array(array($this->sqlBuilder, 'setGroup'), func_get_args());
}
return $this;
}
/**
* Sets having clause, more calls rewrite old value.
* @param string
* @return self
*/
public function having($having)
{
$this->emptyResultSet();
call_user_func_array(array($this->sqlBuilder, 'setHaving'), func_get_args());
return $this;
}
/********************* aggregations ****************d*g**/
/**
* Executes aggregation function.
* @param string select call in "FUNCTION(column)" format
* @return string
*/
public function aggregation($function)
{
$selection = $this->createSelectionInstance();
$selection->getSqlBuilder()->importConditions($this->getSqlBuilder());
$selection->select($function);
foreach ($selection->fetch() as $val) {
return $val;
}
}
/**
* Counts number of rows.
* @param string if it is not provided returns count of result rows, otherwise runs new sql counting query
* @return int
*/
public function count($column = NULL)
{
if (!$column) {
$this->execute();
return count($this->data);
}
return $this->aggregation("COUNT($column)");
}
/**
* Returns minimum value from a column.
* @param string
* @return int
*/
public function min($column)
{
return $this->aggregation("MIN($column)");
}
/**
* Returns maximum value from a column.
* @param string
* @return int
*/
public function max($column)
{
return $this->aggregation("MAX($column)");
}
/**
* Returns sum of values in a column.
* @param string
* @return int
*/
public function sum($column)
{
return $this->aggregation("SUM($column)");
}
/********************* internal ****************d*g**/
protected function execute()
{
if ($this->rows !== NULL) {
return;
}
$this->observeCache = $this;
if ($this->primary === NULL && $this->sqlBuilder->getSelect() === NULL) {
throw new Nette\InvalidStateException('Table with no primary key requires an explicit select clause.');
}
try {
$result = $this->query($this->getSql());
} catch (\PDOException $exception) {
if (!$this->sqlBuilder->getSelect() && $this->previousAccessedColumns) {
$this->previousAccessedColumns = FALSE;
$this->accessedColumns = array();
$result = $this->query($this->getSql());
} else {
throw $exception;
}
}
$this->rows = array();
$usedPrimary = TRUE;
foreach ($result->getPdoStatement() as $key => $row) {
$row = $this->createRow($result->normalizeRow($row));
$primary = $row->getSignature(FALSE);
$usedPrimary = $usedPrimary && $primary;
$this->rows[$primary ?: $key] = $row;
}
$this->data = $this->rows;
if ($usedPrimary && $this->accessedColumns !== FALSE) {
foreach ((array) $this->primary as $primary) {
$this->accessedColumns[$primary] = TRUE;
}
}
}
protected function createRow(array $row)
{
return new ActiveRow($row, $this);
}
public function createSelectionInstance($table = NULL)
{
return new Selection($this->connection, $table ?: $this->name, $this->reflection, $this->cache ? $this->cache->getStorage() : NULL);
}
protected function createGroupedSelectionInstance($table, $column)
{
return new GroupedSelection($this, $table, $column);
}
protected function query($query)
{
return $this->connection->queryArgs($query, $this->sqlBuilder->getParameters());
}
protected function emptyResultSet($saveCache = TRUE)
{
if ($this->rows !== NULL && $saveCache) {
$this->saveCacheState();
}
$this->rows = NULL;
$this->specificCacheKey = NULL;
$this->generalCacheKey = NULL;
$this->refCache['referencingPrototype'] = array();
}
protected function saveCacheState()
{
if ($this->observeCache === $this && $this->cache && !$this->sqlBuilder->getSelect() && $this->accessedColumns !== $this->previousAccessedColumns) {
$previousAccessed = (array) $this->cache->load($this->getGeneralCacheKey());
$accessed = (array) $this->accessedColumns;
$needSave = array_intersect_key($accessed, $previousAccessed) !== $accessed;
if ($needSave) {
$this->cache->save($this->getGeneralCacheKey(), $previousAccessed + $accessed);
$this->previousAccessedColumns = NULL;
}
}
}
/**
* Returns Selection parent for caching.
* @return Selection
*/
protected function getRefTable(& $refPath)
{
return $this;
}
/**
* Loads refCache references
*/
protected function loadRefCache()
{
}
/**
* Returns general cache key indenpendent on query parameters or sql limit
* Used e.g. for previously accessed columns caching
* @return string
*/
protected function getGeneralCacheKey()
{
if ($this->generalCacheKey) {
return $this->generalCacheKey;
}
return $this->generalCacheKey = md5(serialize(array(__CLASS__, $this->name, $this->sqlBuilder->getConditions())));
}
/**
* Returns object specific cache key dependent on query parameters
* Used e.g. for reference memory caching
* @return string
*/
protected function getSpecificCacheKey()
{
if ($this->specificCacheKey) {
return $this->specificCacheKey;
}
return $this->specificCacheKey = md5($this->getSql() . json_encode($this->sqlBuilder->getParameters()));
}
/**
* @internal
* @param string|NULL column name or NULL to reload all columns
* @param bool
*/
public function accessColumn($key, $selectColumn = TRUE)
{
if (!$this->cache) {
return;
}
if ($key === NULL) {
$this->accessedColumns = FALSE;
$currentKey = key((array) $this->data);
} elseif ($this->accessedColumns !== FALSE) {
$this->accessedColumns[$key] = $selectColumn;
}
if ($selectColumn && !$this->sqlBuilder->getSelect() && $this->previousAccessedColumns && ($key === NULL || !isset($this->previousAccessedColumns[$key]))) {
if ($this->sqlBuilder->getLimit()) {
$generalCacheKey = $this->generalCacheKey;
$primaries = array();
foreach ((array) $this->rows as $row) {
$primary = $row->getPrimary();
$primaries[] = is_array($primary) ? array_values($primary) : $primary;
}
}
$this->previousAccessedColumns = array();
$this->emptyResultSet(FALSE);
if ($this->sqlBuilder->getLimit()) {
$this->sqlBuilder->setLimit(NULL, NULL);
$this->wherePrimary($primaries);
$this->generalCacheKey = $generalCacheKey;
}
$this->dataRefreshed = TRUE;
if ($key === NULL) {
// we need to move iterator in resultset
$this->execute();
while (key($this->data) !== $currentKey) {
next($this->data);
}
}
}
}
/**
* @internal
* @param string
*/
public function removeAccessColumn($key)
{
if ($this->cache && is_array($this->accessedColumns)) {
$this->accessedColumns[$key] = FALSE;
}
}
/**
* Returns if selection requeried for more columns.
* @return bool
*/
public function getDataRefreshed()
{
return $this->dataRefreshed;
}
/********************* manipulation ****************d*g**/
/**
* Inserts row in a table.
* @param array|\Traversable|Selection array($column => $value)|\Traversable|Selection for INSERT ... SELECT
* @return IRow|int|bool Returns IRow or number of affected rows for Selection or table without primary key
*/
public function insert($data)
{
if ($data instanceof Selection) {
$data = new Nette\Database\SqlLiteral($data->getSql(), $data->getSqlBuilder()->getParameters());
} elseif ($data instanceof \Traversable) {
$data = iterator_to_array($data);
}
$return = $this->connection->query($this->sqlBuilder->buildInsertQuery(), $data);
if ($data instanceof Nette\Database\SqlLiteral || $this->primary === NULL) {
return $return->getRowCount();
}
$primaryKey = $this->connection->getInsertId($this->getPrimarySequence());
if (is_array($this->getPrimary())) {
$primaryKey = array();
foreach ((array) $this->getPrimary() as $key) {
if (!isset($data[$key])) {
return $data;
}
$primaryKey[$key] = $data[$key];
}
if (count($primaryKey) === 1) {
$primaryKey = reset($primaryKey);
}
}
$row = $this->createSelectionInstance()
->select('*')
->wherePrimary($primaryKey)
->fetch();
$this->loadRefCache();
if ($this->rows !== NULL) {
if ($signature = $row->getSignature(FALSE)) {
$this->rows[$signature] = $row;
$this->data[$signature] = $row;
} else {
$this->rows[] = $row;
$this->data[] = $row;
}
}
return $row;
}
/**
* Updates all rows in result set.
* Joins in UPDATE are supported only in MySQL
* @param array|\Traversable ($column => $value)
* @return int number of affected rows
*/
public function update($data)
{
if ($data instanceof \Traversable) {
$data = iterator_to_array($data);
} elseif (!is_array($data)) {
throw new Nette\InvalidArgumentException;
}
if (!$data) {
return 0;
}
return $this->connection->queryArgs(
$this->sqlBuilder->buildUpdateQuery(),
array_merge(array($data), $this->sqlBuilder->getParameters())
)->getRowCount();
}
/**
* Deletes all rows in result set.
* @return int number of affected rows
*/
public function delete()
{
return $this->query($this->sqlBuilder->buildDeleteQuery())->getRowCount();
}
/********************* references ****************d*g**/
/**
* Returns referenced row.
* @param string
* @param string
* @param mixed primary key to check for $table and $column references
* @return Selection or array() if the row does not exist
*/
public function getReferencedTable($table, $column, $checkPrimaryKey)
{
$referenced = & $this->refCache['referenced'][$this->getSpecificCacheKey()]["$table.$column"];
$selection = & $referenced['selection'];
$cacheKeys = & $referenced['cacheKeys'];
if ($selection === NULL || !isset($cacheKeys[$checkPrimaryKey])) {
$this->execute();
$cacheKeys = array();
foreach ($this->rows as $row) {
if ($row[$column] === NULL) {
continue;
}
$key = $row[$column];
$cacheKeys[$key] = TRUE;
}
if ($cacheKeys) {
$selection = $this->createSelectionInstance($table);
$selection->where($selection->getPrimary(), array_keys($cacheKeys));
} else {
$selection = array();
}
}
return $selection;
}
/**
* Returns referencing rows.
* @param string
* @param string
* @param int primary key
* @return GroupedSelection
*/
public function getReferencingTable($table, $column, $active = NULL)
{
$prototype = & $this->refCache['referencingPrototype']["$table.$column"];
if (!$prototype) {
$prototype = $this->createGroupedSelectionInstance($table, $column);
$prototype->where("$table.$column", array_keys((array) $this->rows));
}
$clone = clone $prototype;
$clone->setActive($active);
return $clone;
}
/********************* interface Iterator ****************d*g**/
public function rewind()
{
$this->execute();
$this->keys = array_keys($this->data);
reset($this->keys);
}
/** @return IRow */
public function current()
{
if (($key = current($this->keys)) !== FALSE) {
return $this->data[$key];
} else {
return FALSE;
}
}
/**
* @return string row ID
*/
public function key()
{
return current($this->keys);
}
public function next()
{
next($this->keys);
}
public function valid()
{
return current($this->keys) !== FALSE;
}
/********************* interface ArrayAccess ****************d*g**/
/**
* Mimic row.
* @param string row ID
* @param IRow
* @return NULL
*/
public function offsetSet($key, $value)
{
$this->execute();
$this->rows[$key] = $value;
}
/**
* Returns specified row.
* @param string row ID
* @return IRow or NULL if there is no such row
*/
public function offsetGet($key)
{
$this->execute();
return $this->rows[$key];
}
/**
* Tests if row exists.
* @param string row ID
* @return bool
*/
public function offsetExists($key)
{
$this->execute();
return isset($this->rows[$key]);
}
/**
* Removes row from result set.
* @param string row ID
* @return NULL
*/
public function offsetUnset($key)
{
$this->execute();
unset($this->rows[$key], $this->data[$key]);
}
}
Nette-2.1.0/Nette/Database/Table/SqlBuilder.php 100777 0 0 32033 12261522617 14326 0 array(),
'where' => array(),
'group' => array(),
'having' => array(),
'order' => array(),
);
/** @var array or columns to order by */
protected $order = array();
/** @var int number of rows to fetch */
protected $limit = NULL;
/** @var int first row to fetch */
protected $offset = NULL;
/** @var string columns to grouping */
protected $group = '';
/** @var string grouping condition */
protected $having = '';
public function __construct($tableName, Connection $connection, IReflection $reflection)
{
$this->tableName = $tableName;
$this->databaseReflection = $reflection;
$this->driver = $connection->getSupplementalDriver();
$this->delimitedTable = $this->tryDelimite($tableName);
}
public function buildInsertQuery()
{
return "INSERT INTO {$this->delimitedTable}";
}
public function buildUpdateQuery()
{
if ($this->limit !== NULL || $this->offset) {
throw new Nette\NotSupportedException('LIMIT clause is not supported in UPDATE query.');
}
return $this->tryDelimite("UPDATE {$this->tableName} SET ?" . $this->buildConditions());
}
public function buildDeleteQuery()
{
if ($this->limit !== NULL || $this->offset) {
throw new Nette\NotSupportedException('LIMIT clause is not supported in DELETE query.');
}
return $this->tryDelimite("DELETE FROM {$this->tableName}" . $this->buildConditions());
}
/**
* Returns SQL query.
* @param string list of columns
* @return string
*/
public function buildSelectQuery($columns = NULL)
{
$queryCondition = $this->buildConditions();
$queryEnd = $this->buildQueryEnd();
$joins = array();
$this->parseJoins($joins, $queryCondition);
$this->parseJoins($joins, $queryEnd);
if ($this->select) {
$querySelect = $this->buildSelect($this->select);
$this->parseJoins($joins, $querySelect);
} elseif ($columns) {
$prefix = $joins ? "{$this->delimitedTable}." : '';
$cols = array();
foreach ($columns as $col) {
$cols[] = $prefix . $col;
}
$querySelect = $this->buildSelect($cols);
} elseif ($this->group && !$this->driver->isSupported(ISupplementalDriver::SUPPORT_SELECT_UNGROUPED_COLUMNS)) {
$querySelect = $this->buildSelect(array($this->group));
$this->parseJoins($joins, $querySelect);
} else {
$prefix = $joins ? "{$this->delimitedTable}." : '';
$querySelect = $this->buildSelect(array($prefix . '*'));
}
$queryJoins = $this->buildQueryJoins($joins);
$query = "{$querySelect} FROM {$this->tableName}{$queryJoins}{$queryCondition}{$queryEnd}";
if ($this->limit !== NULL || $this->offset) {
$this->driver->applyLimit($query, $this->limit, $this->offset);
}
return $this->tryDelimite($query);
}
public function getParameters()
{
return array_merge(
$this->parameters['select'],
$this->parameters['where'],
$this->parameters['group'],
$this->parameters['having'],
$this->parameters['order']
);
}
public function importConditions(SqlBuilder $builder)
{
$this->where = $builder->where;
$this->parameters['where'] = $builder->parameters['where'];
$this->conditions = $builder->conditions;
}
/********************* SQL selectors ****************d*g**/
public function addSelect($columns)
{
if (is_array($columns)) {
throw new Nette\InvalidArgumentException('Select column must be a string.');
}
$this->select[] = $columns;
$this->parameters['select'] = array_merge($this->parameters['select'], array_slice(func_get_args(), 1));
}
public function getSelect()
{
return $this->select;
}
public function addWhere($condition, $parameters = array())
{
if (is_array($condition) && is_array($parameters) && !empty($parameters)) {
return $this->addWhereComposition($condition, $parameters);
}
$args = func_get_args();
$hash = md5(json_encode($args));
if (isset($this->conditions[$hash])) {
return FALSE;
}
$this->conditions[$hash] = $condition;
$placeholderCount = substr_count($condition, '?');
if ($placeholderCount > 1 && count($args) === 2 && is_array($parameters)) {
$args = $parameters;
} else {
array_shift($args);
}
$condition = trim($condition);
if ($placeholderCount === 0 && count($args) === 1) {
$condition .= ' ?';
} elseif ($placeholderCount !== count($args)) {
throw new Nette\InvalidArgumentException('Argument count does not match placeholder count.');
}
$replace = NULL;
$placeholderNum = 0;
foreach ($args as $arg) {
preg_match('#(?:.*?\?.*?){' . $placeholderNum . '}(((?:&|\||^|~|\+|-|\*|/|%|\(|,|<|>|=|(?<=\W|^)(?:REGEXP|ALL|AND|ANY|BETWEEN|EXISTS|IN|[IR]?LIKE|OR|NOT|SOME|INTERVAL))\s*)?(?:\(\?\)|\?))#s', $condition, $match, PREG_OFFSET_CAPTURE);
$hasOperator = ($match[1][0] === '?' && $match[1][1] === 0) ? TRUE : !empty($match[2][0]);
if ($arg === NULL) {
if ($hasOperator) {
throw new Nette\InvalidArgumentException('Column operator does not accept NULL argument.');
}
$replace = 'IS NULL';
} elseif (is_array($arg) || $arg instanceof Selection) {
if ($hasOperator) {
if (trim($match[2][0]) === 'NOT') {
$match[2][0] = rtrim($match[2][0]) . ' IN ';
} elseif (trim($match[2][0]) !== 'IN') {
throw new Nette\InvalidArgumentException('Column operator does not accept array argument.');
}
} else {
$match[2][0] = 'IN ';
}
if ($arg instanceof Selection) {
$clone = clone $arg;
if (!$clone->getSqlBuilder()->select) {
try {
$clone->select($clone->getPrimary());
} catch (\LogicException $e) {
throw new Nette\InvalidArgumentException('Selection argument must have defined a select column.', 0, $e);
}
}
if ($this->driver->isSupported(ISupplementalDriver::SUPPORT_SUBSELECT)) {
$arg = NULL;
$replace = $match[2][0] . '(' . $clone->getSql() . ')';
$this->parameters['where'] = array_merge($this->parameters['where'], $clone->getSqlBuilder()->parameters['where']);
} else {
$arg = array();
foreach ($clone as $row) {
$arg[] = array_values(iterator_to_array($row));
}
}
}
if ($arg !== NULL) {
if (!$arg) {
$hasBrackets = strpos($condition, '(') !== FALSE;
$hasOperators = preg_match('#AND|OR#', $condition);
$hasNot = strpos($condition, 'NOT') !== FALSE;
$hasPrefixNot = strpos($match[2][0], 'NOT') !== FALSE;
if (!$hasBrackets && ($hasOperators || ($hasNot && !$hasPrefixNot))) {
throw new Nette\InvalidArgumentException('Possible SQL query corruption. Add parentheses around operators.');
}
if ($hasPrefixNot) {
$replace = 'IS NULL OR TRUE';
} else {
$replace = 'IS NULL AND FALSE';
}
$arg = NULL;
} else {
$replace = $match[2][0] . '(?)';
$this->parameters['where'][] = $arg;
}
}
} elseif ($arg instanceof SqlLiteral) {
$this->parameters['where'][] = $arg;
} else {
if (!$hasOperator) {
$replace = '= ?';
}
$this->parameters['where'][] = $arg;
}
if ($replace) {
$condition = substr_replace($condition, $replace, $match[1][1], strlen($match[1][0]));
$replace = NULL;
}
if ($arg !== NULL) {
$placeholderNum++;
}
}
$this->where[] = $condition;
return TRUE;
}
public function getConditions()
{
return array_values($this->conditions);
}
public function addOrder($columns)
{
$this->order[] = $columns;
$this->parameters['order'] = array_merge($this->parameters['order'], array_slice(func_get_args(), 1));
}
public function getOrder()
{
return $this->order;
}
public function setLimit($limit, $offset)
{
$this->limit = $limit;
$this->offset = $offset;
}
public function getLimit()
{
return $this->limit;
}
public function getOffset()
{
return $this->offset;
}
public function setGroup($columns)
{
$this->group = $columns;
$this->parameters['group'] = array_slice(func_get_args(), 1);
}
public function getGroup()
{
return $this->group;
}
public function setHaving($having)
{
$this->having = $having;
$this->parameters['having'] = array_slice(func_get_args(), 1);
}
public function getHaving()
{
return $this->having;
}
/********************* SQL building ****************d*g**/
protected function buildSelect(array $columns)
{
return 'SELECT ' . implode(', ', $columns);
}
protected function parseJoins(& $joins, & $query)
{
$builder = $this;
$query = preg_replace_callback('~
(?(DEFINE)
(?P [a-z][\w_]* )
(?P [.:] )
(?P (?&del)? (?&word) (\((?&word)\))? )
)
(?P (?!\.) (?&node)*) \. (?P (?&word) | \* )
~xi', function($match) use (& $joins, $builder) {
return $builder->parseJoinsCb($joins, $match);
}, $query);
}
public function parseJoinsCb(& $joins, $match)
{
$chain = $match['chain'];
if (!empty($chain[0]) && ($chain[0] !== '.' || $chain[0] !== ':')) {
$chain = '.' . $chain; // unified chain format
}
$parent = $parentAlias = $this->tableName;
if ($chain == ".{$parent}") { // case-sensitive
return "{$parent}.{$match['column']}";
}
preg_match_all('~
(?(DEFINE)
(?P [a-z][\w_]* )
)
(?P [.:])?(?P (?&word))(\((?P (?&word))\))?
~xi', $chain, $keyMatches, PREG_SET_ORDER);
foreach ($keyMatches as $keyMatch) {
if ($keyMatch['del'] === ':') {
if (isset($keyMatch['throughColumn'])) {
$table = $keyMatch['key'];
list(, $primary) = $this->databaseReflection->getBelongsToReference($table, $keyMatch['throughColumn']);
} else {
list($table, $primary) = $this->databaseReflection->getHasManyReference($parent, $keyMatch['key']);
}
$column = $this->databaseReflection->getPrimary($parent);
} else {
list($table, $column) = $this->databaseReflection->getBelongsToReference($parent, $keyMatch['key']);
$primary = $this->databaseReflection->getPrimary($table);
}
$joins[$table . $column] = array($table, $keyMatch['key'] ?: $table, $parentAlias, $column, $primary);
$parent = $table;
$parentAlias = $keyMatch['key'];
}
return ($keyMatch['key'] ?: $table) . ".{$match['column']}";
}
protected function buildQueryJoins(array $joins)
{
$return = '';
foreach ($joins as $join) {
list($joinTable, $joinAlias, $table, $tableColumn, $joinColumn) = $join;
$return .=
" LEFT JOIN {$joinTable}" . ($joinTable !== $joinAlias ? " AS {$joinAlias}" : '') .
" ON {$table}.{$tableColumn} = {$joinAlias}.{$joinColumn}";
}
return $return;
}
protected function buildConditions()
{
return $this->where ? ' WHERE (' . implode(') AND (', $this->where) . ')' : '';
}
protected function buildQueryEnd()
{
$return = '';
if ($this->group) {
$return .= ' GROUP BY '. $this->group;
}
if ($this->having) {
$return .= ' HAVING '. $this->having;
}
if ($this->order) {
$return .= ' ORDER BY ' . implode(', ', $this->order);
}
return $return;
}
protected function tryDelimite($s)
{
$driver = $this->driver;
return preg_replace_callback('#(?<=[^\w`"\[]|^)[a-z_][a-z0-9_]*(?=[^\w`"(\]]|\z)#i', function($m) use ($driver) {
return strtoupper($m[0]) === $m[0] ? $m[0] : $driver->delimite($m[0]);
}, $s);
}
protected function addWhereComposition(array $columns, array $parameters)
{
if ($this->driver->isSupported(ISupplementalDriver::SUPPORT_MULTI_COLUMN_AS_OR_COND)) {
$conditionFragment = '(' . implode(' = ? AND ', $columns) . ' = ?) OR ';
$condition = substr(str_repeat($conditionFragment, count($parameters)), 0, -4);
return $this->addWhere($condition, Nette\Utils\Arrays::flatten($parameters));
} else {
return $this->addWhere('(' . implode(', ', $columns) . ') IN', $parameters);
}
}
}
Nette-2.1.0/Nette/DI/ 40777 0 0 0 12261522617 7167 5 Nette-2.1.0/Nette/Diagnostics/ 40777 0 0 0 12261522617 11142 5 Nette-2.1.0/Nette/Diagnostics/Bar.php 100777 0 0 4350 12261522617 12461 0 panels[$id]));
}
$this->panels[$id] = $panel;
return $this;
}
/**
* Returns panel with given id
* @param string
* @return IBarPanel|NULL
*/
public function getPanel($id)
{
return isset($this->panels[$id]) ? $this->panels[$id] : NULL;
}
/**
* Renders debug bar.
* @return void
*/
public function render()
{
$obLevel = ob_get_level();
$panels = array();
foreach ($this->panels as $id => $panel) {
try {
$panels[] = array(
'id' => preg_replace('#[^a-z0-9]+#i', '-', $id),
'tab' => $tab = (string) $panel->getTab(),
'panel' => $tab ? (string) $panel->getPanel() : NULL,
);
} catch (\Exception $e) {
$panels[] = array(
'id' => "error-" . preg_replace('#[^a-z0-9]+#i', '-', $id),
'tab' => "Error in $id",
'panel' => 'Error: ' . $id . '
' . nl2br(htmlSpecialChars($e, ENT_IGNORE)) . '
',
);
while (ob_get_level() > $obLevel) { // restore ob-level if broken
ob_end_clean();
}
}
}
@session_start();
$session = & $_SESSION['__NF']['debuggerbar'];
if (preg_match('#^Location:#im', implode("\n", headers_list()))) {
$session[] = $panels;
return;
}
foreach (array_reverse((array) $session) as $reqId => $oldpanels) {
$panels[] = array(
'tab' => 'previous',
'panel' => NULL,
'previous' => TRUE,
);
foreach ($oldpanels as $panel) {
$panel['id'] .= '-' . $reqId;
$panels[] = $panel;
}
}
$session = NULL;
require __DIR__ . '/templates/bar.phtml';
}
}
Nette-2.1.0/Nette/Diagnostics/BlueScreen.php 100777 0 0 7776 12261522617 14023 0 panels, TRUE)) {
$this->panels[] = $panel;
}
return $this;
}
/**
* Renders blue screen.
* @param \Exception
* @return void
*/
public function render(\Exception $exception)
{
$panels = $this->panels;
require __DIR__ . '/templates/bluescreen.phtml';
}
/**
* Returns syntax highlighted source code.
* @param string
* @param int
* @param int
* @return string
*/
public static function highlightFile($file, $line, $lines = 15, $vars = array())
{
$source = @file_get_contents($file); // intentionally @
if ($source) {
return substr_replace(
static::highlightPhp($source, $line, $lines, $vars),
' data-nette-href="' . htmlspecialchars(strtr(Debugger::$editor, array('%file' => rawurlencode($file), '%line' => $line))) . '"',
4, 0
);
}
}
/**
* Returns syntax highlighted source code.
* @param string
* @param int
* @param int
* @return string
*/
public static function highlightPhp($source, $line, $lines = 15, $vars = array())
{
if (function_exists('ini_set')) {
ini_set('highlight.comment', '#998; font-style: italic');
ini_set('highlight.default', '#000');
ini_set('highlight.html', '#06B');
ini_set('highlight.keyword', '#D24; font-weight: bold');
ini_set('highlight.string', '#080');
}
$source = str_replace(array("\r\n", "\r"), "\n", $source);
$source = explode("\n", highlight_string($source, TRUE));
$out = $source[0]; //
$source = str_replace('
', "\n", $source[1]);
$out .= static::highlightLine($source, $line, $lines);
$out = preg_replace_callback('#">\$(\w+)( )?#', function($m) use ($vars) {
return isset($vars[$m[1]])
? '" title="' . str_replace('"', '"', strip_tags(Dumper::toHtml($vars[$m[1]]))) . $m[0]
: $m[0];
}, $out);
return "$out
";
}
/**
* Returns highlighted line in HTML code.
* @return string
*/
public static function highlightLine($html, $line, $lines = 15)
{
$source = explode("\n", "\n" . str_replace("\r\n", "\n", $html));
$out = '';
$spans = 1;
$start = $i = max(1, $line - floor($lines * 2/3));
while (--$i >= 1) { // find last highlighted block
if (preg_match('#.*(?span[^>]*>)#', $source[$i], $m)) {
if ($m[1] !== '') {
$spans++;
$out .= $m[1];
}
break;
}
}
$source = array_slice($source, $start, $lines, TRUE);
end($source);
$numWidth = strlen((string) key($source));
foreach ($source as $n => $s) {
$spans += substr_count($s, ']+>#', $s, $tags);
if ($n == $line) {
$out .= sprintf(
"%{$numWidth}s: %s\n%s",
$n,
strip_tags($s),
implode('', $tags[0])
);
} else {
$out .= sprintf("%{$numWidth}s: %s\n", $n, $s);
}
}
$out .= str_repeat('', $spans) . '
';
return $out;
}
/**
* Should a file be collapsed in stack trace?
* @param string
* @return bool
*/
public function isCollapsed($file)
{
foreach ($this->collapsePaths as $path) {
if (strpos(strtr($file, '\\', '/'), strtr("$path/", '\\', '/')) === 0) {
return TRUE;
}
}
return FALSE;
}
}
Nette-2.1.0/Nette/Diagnostics/Debugger.php 100777 0 0 50224 12261522617 13522 0 'Fatal Error',
E_USER_ERROR => 'User Error',
E_RECOVERABLE_ERROR => 'Recoverable Error',
E_CORE_ERROR => 'Core Error',
E_COMPILE_ERROR => 'Compile Error',
E_PARSE => 'Parse Error',
E_WARNING => 'Warning',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_WARNING => 'User Warning',
E_NOTICE => 'Notice',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Strict standards',
E_DEPRECATED => 'Deprecated',
E_USER_DEPRECATED => 'User Deprecated',
);
/********************* logging ****************d*g**/
/** @deprecated @var Logger */
public static $logger;
/** @deprecated @var FireLogger */
public static $fireLogger;
/** @var string name of the directory where errors should be logged; FALSE means that logging is disabled */
public static $logDirectory;
/** @var string|array email(s) to which send error notifications */
public static $email;
/** @deprecated */
public static $mailer = array('Nette\Diagnostics\Logger', 'defaultMailer');
/** @deprecated */
public static $emailSnooze = 172800;
/** {@link Debugger::log()} and {@link Debugger::fireLog()} */
const DEBUG = 'debug',
INFO = 'info',
WARNING = 'warning',
ERROR = 'error',
CRITICAL = 'critical';
/********************* debug bar ****************d*g**/
/** @deprecated @var Bar */
public static $bar;
/**
* Static class - cannot be instantiated.
*/
final public function __construct()
{
throw new Nette\StaticClassException;
}
/**
* Enables displaying or logging errors and exceptions.
* @param mixed production, development mode, autodetection or IP address(es) whitelist.
* @param string error log directory; enables logging in production mode, FALSE means that logging is disabled
* @param string administrator email; enables email sending in production mode
* @return void
*/
public static function enable($mode = NULL, $logDirectory = NULL, $email = NULL)
{
self::$time = isset($_SERVER['REQUEST_TIME_FLOAT']) ? $_SERVER['REQUEST_TIME_FLOAT'] : microtime(TRUE);
if (isset($_SERVER['REQUEST_URI'])) {
self::$source = (isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off') ? 'https://' : 'http://')
. (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '')
. $_SERVER['REQUEST_URI'];
} else {
self::$source = empty($_SERVER['argv']) ? 'CLI' : 'CLI: ' . implode(' ', $_SERVER['argv']);
}
self::$consoleColors = & Dumper::$terminalColors;
error_reporting(E_ALL | E_STRICT);
// production/development mode detection
if (is_bool($mode)) {
self::$productionMode = $mode;
} elseif ($mode !== self::DETECT || self::$productionMode === NULL) { // IP addresses or computer names whitelist detection
$list = is_string($mode) ? preg_split('#[,\s]+#', $mode) : (array) $mode;
if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$list[] = '127.0.0.1';
$list[] = '::1';
}
self::$productionMode = !in_array(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : php_uname('n'), $list, TRUE);
}
// logging configuration
if (is_string($logDirectory)) {
self::$logDirectory = realpath($logDirectory);
if (self::$logDirectory === FALSE) {
echo __METHOD__ . "() error: Log directory is not found or is not directory.\n";
exit(254);
}
} elseif ($logDirectory === FALSE || self::$logDirectory === NULL) {
self::$logDirectory = FALSE;
}
if (self::$logDirectory) {
ini_set('error_log', self::$logDirectory . '/php_error.log');
}
// php configuration
if (function_exists('ini_set')) {
ini_set('display_errors', !self::$productionMode); // or 'stderr'
ini_set('html_errors', FALSE);
ini_set('log_errors', FALSE);
} elseif (ini_get('display_errors') != !self::$productionMode && ini_get('display_errors') !== (self::$productionMode ? 'stderr' : 'stdout')) { // intentionally ==
echo __METHOD__ . "() error: Unable to set 'display_errors' because function ini_set() is disabled.\n";
exit(254);
}
if ($email) {
if (!is_string($email) && !is_array($email)) {
echo __METHOD__ . "() error: Email address must be a string.\n";
exit(254);
}
self::$email = $email;
}
if (!self::$enabled) {
register_shutdown_function(array(__CLASS__, '_shutdownHandler'));
set_exception_handler(array(__CLASS__, '_exceptionHandler'));
set_error_handler(array(__CLASS__, '_errorHandler'));
foreach (array('Nette\Diagnostics\Bar', 'Nette\Diagnostics\BlueScreen', 'Nette\Diagnostics\DefaultBarPanel', 'Nette\Diagnostics\Dumper', 'Nette\Diagnostics\FireLogger',
'Nette\Diagnostics\Helpers', 'Nette\Diagnostics\Logger', 'Nette\Utils\Html', 'Nette\Utils\Strings') as $class) {
class_exists($class);
}
self::$enabled = TRUE;
}
}
/**
* @return BlueScreen
*/
public static function getBlueScreen()
{
if (!self::$blueScreen) {
self::$blueScreen = new BlueScreen;
self::$blueScreen->collapsePaths[] = dirname(__DIR__);
self::$blueScreen->addPanel(function($e) {
if ($e instanceof Nette\Templating\FilterException) {
return array(
'tab' => 'Template',
'panel' => 'File: ' . Helpers::editorLink($e->sourceFile, $e->sourceLine) . '
'
. ($e->sourceLine ? BlueScreen::highlightFile($e->sourceFile, $e->sourceLine) : '')
);
} elseif ($e instanceof Nette\Utils\NeonException && preg_match('#line (\d+)#', $e->getMessage(), $m)) {
if ($item = Helpers::findTrace($e->getTrace(), 'Nette\DI\Config\Adapters\NeonAdapter::load')) {
return array(
'tab' => 'NEON',
'panel' => 'File: ' . Helpers::editorLink($item['args'][0], $m[1]) . '
'
. BlueScreen::highlightFile($item['args'][0], $m[1])
);
} elseif ($item = Helpers::findTrace($e->getTrace(), 'Nette\Utils\Neon::decode')) {
return array(
'tab' => 'NEON',
'panel' => BlueScreen::highlightPhp($item['args'][0], $m[1])
);
}
}
});
}
return self::$blueScreen;
}
/**
* @return Bar
*/
public static function getBar()
{
if (!self::$bar) {
self::$bar = new Bar;
self::$bar->addPanel(new DefaultBarPanel('time'));
self::$bar->addPanel(new DefaultBarPanel('memory'));
self::$bar->addPanel(new DefaultBarPanel('errors'), __CLASS__ . ':errors'); // filled by _errorHandler()
self::$bar->addPanel(new DefaultBarPanel('dumps'), __CLASS__ . ':dumps'); // filled by barDump()
}
return self::$bar;
}
/**
* @return void
*/
public static function setLogger($logger)
{
self::$logger = $logger;
}
/**
* @return Logger
*/
public static function getLogger()
{
if (!self::$logger) {
self::$logger = new Logger;
self::$logger->directory = & self::$logDirectory;
self::$logger->email = & self::$email;
self::$logger->mailer = & self::$mailer;
self::$logger->emailSnooze = & self::$emailSnooze;
}
return self::$logger;
}
/**
* @return FireLogger
*/
public static function getFireLogger()
{
if (!self::$fireLogger) {
self::$fireLogger = new FireLogger;
}
return self::$fireLogger;
}
/**
* Is Debug enabled?
* @return bool
*/
public static function isEnabled()
{
return self::$enabled;
}
/**
* Logs message or exception to file (if not disabled) and sends email notification (if enabled).
* @param string|Exception
* @param int one of constant Debugger::INFO, WARNING, ERROR (sends email), CRITICAL (sends email)
* @return string logged error filename
*/
public static function log($message, $priority = self::INFO)
{
if (self::$logDirectory === FALSE) {
return;
} elseif (!self::$logDirectory) {
throw new Nette\InvalidStateException('Logging directory is not specified in Nette\Diagnostics\Debugger::$logDirectory.');
}
$exceptionFilename = NULL;
if ($message instanceof \Exception) {
$exception = $message;
while ($exception) {
$tmp[] = ($exception instanceof ErrorException
? 'Fatal error: ' . $exception->getMessage()
: get_class($exception) . ": " . $exception->getMessage())
. " in " . $exception->getFile() . ":" . $exception->getLine();
$exception = $exception->getPrevious();
}
$exception = $message;
$message = implode($tmp, "\ncaused by ");
$hash = md5(preg_replace('~(Resource id #)\d+~', '$1', $exception));
$exceptionFilename = "exception-" . @date('Y-m-d-H-i-s') . "-$hash.html";
foreach (new \DirectoryIterator(self::$logDirectory) as $entry) {
if (strpos($entry, $hash)) {
$exceptionFilename = $entry;
$saved = TRUE;
break;
}
}
} elseif (!is_string($message)) {
$message = Dumper::toText($message);
}
if ($exceptionFilename) {
$exceptionFilename = self::$logDirectory . '/' . $exceptionFilename;
if (empty($saved) && $logHandle = @fopen($exceptionFilename, 'w')) {
ob_start(); // double buffer prevents sending HTTP headers in some PHP
ob_start(function($buffer) use ($logHandle) { fwrite($logHandle, $buffer); }, 4096);
self::getBlueScreen()->render($exception);
ob_end_flush();
ob_end_clean();
fclose($logHandle);
}
}
self::getLogger()->log(array(
@date('[Y-m-d H-i-s]'),
trim($message),
self::$source ? ' @ ' . self::$source : NULL,
$exceptionFilename ? ' @@ ' . basename($exceptionFilename) : NULL
), $priority);
return $exceptionFilename ? strtr($exceptionFilename, '\\/', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR) : NULL;
}
/**
* Shutdown handler to catch fatal errors and execute of the planned activities.
* @return void
* @internal
*/
public static function _shutdownHandler()
{
if (!self::$enabled) {
return;
}
$error = error_get_last();
if (in_array($error['type'], array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE))) {
self::_exceptionHandler(Helpers::fixStack(new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])), TRUE);
} elseif (!connection_aborted() && !self::$productionMode && self::isHtmlMode()) {
self::getBar()->render();
}
}
/**
* Handler to catch uncaught exception.
* @param \Exception
* @return void
* @internal
*/
public static function _exceptionHandler(\Exception $exception, $shutdown = FALSE)
{
if (!self::$enabled) {
return;
}
self::$enabled = FALSE; // prevent double rendering
if (!headers_sent()) {
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
$code = isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') !== FALSE ? 503 : 500;
header("$protocol $code", TRUE, $code);
}
try {
if (self::$productionMode) {
try {
self::log($exception, self::ERROR);
} catch (\Exception $e) {
echo 'FATAL ERROR: unable to log error';
}
if (self::isHtmlMode()) {
require __DIR__ . '/templates/error.phtml';
} else {
echo "ERROR: the server encountered an internal error and was unable to complete your request.\n";
}
} else {
if (!connection_aborted() && self::isHtmlMode()) {
self::getBlueScreen()->render($exception);
self::getBar()->render();
} elseif (connection_aborted() || !self::fireLog($exception)) {
$file = self::log($exception, self::ERROR);
if (!headers_sent()) {
header("X-Nette-Error-Log: $file");
}
echo "$exception\n" . ($file ? "(stored in $file)\n" : '');
if (self::$browser) {
exec(self::$browser . ' ' . escapeshellarg($file));
}
}
}
foreach (self::$onFatalError as $handler) {
call_user_func($handler, $exception);
}
} catch (\Exception $e) {
if (self::$productionMode) {
echo self::isHtmlMode() ? 'FATAL ERROR' : 'FATAL ERROR';
} else {
echo "FATAL ERROR: thrown ", get_class($e), ': ', $e->getMessage(),
"\nwhile processing ", get_class($exception), ': ', $exception->getMessage(), "\n";
}
}
if (!$shutdown) {
exit(254);
}
}
/**
* Handler to catch warnings and notices.
* @param int level of the error raised
* @param string error message
* @param string file that the error was raised in
* @param int line number the error was raised at
* @param array an array of variables that existed in the scope the error was triggered in
* @return bool FALSE to call normal error handler, NULL otherwise
* @throws ErrorException
* @internal
*/
public static function _errorHandler($severity, $message, $file, $line, $context)
{
if (self::$scream) {
error_reporting(E_ALL | E_STRICT);
}
if (self::$lastError !== FALSE && ($severity & error_reporting()) === $severity) { // tryError mode
self::$lastError = new \ErrorException($message, 0, $severity, $file, $line);
return NULL;
}
if ($severity === E_RECOVERABLE_ERROR || $severity === E_USER_ERROR) {
if (Helpers::findTrace(debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE), '*::__toString')) {
$previous = isset($context['e']) && $context['e'] instanceof \Exception ? $context['e'] : NULL;
$e = new ErrorException($message, 0, $severity, $file, $line, $previous);
$e->context = $context;
self::_exceptionHandler($e);
}
$e = new ErrorException($message, 0, $severity, $file, $line);
$e->context = $context;
throw $e;
} elseif (($severity & error_reporting()) !== $severity) {
return FALSE; // calls normal error handler to fill-in error_get_last()
} elseif (!self::$productionMode && (is_bool(self::$strictMode) ? self::$strictMode : ((self::$strictMode & $severity) === $severity))) {
$e = new ErrorException($message, 0, $severity, $file, $line);
$e->context = $context;
self::_exceptionHandler($e);
}
$message = 'PHP ' . (isset(self::$errorTypes[$severity]) ? self::$errorTypes[$severity] : 'Unknown error') . ": $message";
$count = & self::getBar()->getPanel(__CLASS__ . ':errors')->data["$file|$line|$message"];
if ($count++) { // repeated error
return NULL;
} elseif (self::$productionMode) {
self::log("$message in $file:$line", self::ERROR);
return NULL;
} else {
self::fireLog(new ErrorException($message, 0, $severity, $file, $line));
return self::isHtmlMode() ? NULL : FALSE; // FALSE calls normal error handler
}
}
/** @deprecated */
public static function toStringException(\Exception $exception)
{
trigger_error(__METHOD__ . '() is deprecated; use trigger_error(..., E_USER_ERROR) instead.', E_USER_DEPRECATED);
if (self::$enabled) {
self::_exceptionHandler($exception);
} else {
trigger_error($exception->getMessage(), E_USER_ERROR);
}
}
/** @deprecated */
public static function tryError()
{
trigger_error(__METHOD__ . '() is deprecated; use own error handler instead.', E_USER_DEPRECATED);
if (!self::$enabled && self::$lastError === FALSE) {
set_error_handler(array(__CLASS__, '_errorHandler'));
}
self::$lastError = NULL;
}
/** @deprecated */
public static function catchError(& $error)
{
trigger_error(__METHOD__ . '() is deprecated; use own error handler instead.', E_USER_DEPRECATED);
if (!self::$enabled && self::$lastError !== FALSE) {
restore_error_handler();
}
$error = self::$lastError;
self::$lastError = FALSE;
return (bool) $error;
}
/********************* useful tools ****************d*g**/
/**
* Dumps information about a variable in readable format.
* @param mixed variable to dump
* @param bool return output instead of printing it? (bypasses $productionMode)
* @return mixed variable itself or dump
*/
public static function dump($var, $return = FALSE)
{
if ($return) {
ob_start();
Dumper::dump($var, array(
Dumper::DEPTH => self::$maxDepth,
Dumper::TRUNCATE => self::$maxLen,
));
return ob_get_clean();
} elseif (!self::$productionMode) {
Dumper::dump($var, array(
Dumper::DEPTH => self::$maxDepth,
Dumper::TRUNCATE => self::$maxLen,
Dumper::LOCATION => self::$showLocation,
));
}
return $var;
}
/**
* Starts/stops stopwatch.
* @param string name
* @return float elapsed seconds
*/
public static function timer($name = NULL)
{
static $time = array();
$now = microtime(TRUE);
$delta = isset($time[$name]) ? $now - $time[$name] : 0;
$time[$name] = $now;
return $delta;
}
/**
* Dumps information about a variable in Nette Debug Bar.
* @param mixed variable to dump
* @param string optional title
* @param array dumper options
* @return mixed variable itself
*/
public static function barDump($var, $title = NULL, array $options = NULL)
{
if (!self::$productionMode) {
self::getBar()->getPanel(__CLASS__ . ':dumps')->data[] = array('title' => $title, 'dump' => Dumper::toHtml($var, (array) $options + array(
Dumper::DEPTH => self::$maxDepth,
Dumper::TRUNCATE => self::$maxLen,
Dumper::LOCATION => self::$showLocation,
)));
}
return $var;
}
/**
* Sends message to FireLogger console.
* @param mixed message to log
* @return bool was successful?
*/
public static function fireLog($message)
{
if (!self::$productionMode) {
return self::getFireLogger()->log($message);
}
}
private static function isHtmlMode()
{
return empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& PHP_SAPI !== 'cli'
&& !preg_match('#^Content-Type: (?!text/html)#im', implode("\n", headers_list()));
}
public static function addPanel(IBarPanel $panel, $id = NULL)
{
return self::getBar()->addPanel($panel, $id);
}
}
Nette-2.1.0/Nette/Diagnostics/DefaultBarPanel.php 100777 0 0 1706 12261522617 14750 0 id = $id;
}
/**
* Renders HTML code for custom tab.
* @return string
*/
public function getTab()
{
ob_start();
require __DIR__ . "/templates/bar.{$this->id}.tab.phtml";
return ob_get_clean();
}
/**
* Renders HTML code for custom panel.
* @return string
*/
public function getPanel()
{
ob_start();
if (is_file(__DIR__ . "/templates/bar.{$this->id}.panel.phtml")) {
require __DIR__ . "/templates/bar.{$this->id}.panel.phtml";
}
return ob_get_clean();
}
}
Nette-2.1.0/Nette/Diagnostics/Dumper.php 100777 0 0 23765 12261522617 13244 0 '1;33',
'null' => '1;33',
'number' => '1;32',
'string' => '1;36',
'array' => '1;31',
'key' => '1;37',
'object' => '1;31',
'visibility' => '1;30',
'resource' => '1;37',
'indent' => '1;30',
);
/** @var array */
public static $resources = array(
'stream' => 'stream_get_meta_data',
'stream-context' => 'stream_context_get_options',
'curl' => 'curl_getinfo',
);
/**
* Dumps variable to the output.
* @return mixed variable
*/
public static function dump($var, array $options = NULL)
{
if (PHP_SAPI !== 'cli' && !preg_match('#^Content-Type: (?!text/html)#im', implode("\n", headers_list()))) {
echo self::toHtml($var, $options);
} elseif (self::detectColors()) {
echo self::toTerminal($var, $options);
} else {
echo self::toText($var, $options);
}
return $var;
}
/**
* Dumps variable to HTML.
* @return string
*/
public static function toHtml($var, array $options = NULL)
{
$options = (array) $options + array(
self::DEPTH => 4,
self::TRUNCATE => 150,
self::COLLAPSE => FALSE,
self::COLLAPSE_COUNT => 7,
self::LOCATION => FALSE,
);
list($file, $line, $code) = $options[self::LOCATION] ? self::findLocation() : NULL;
return '' : '>')
. self::dumpVar($var, $options)
. ($file ? 'in " . htmlspecialchars($file, ENT_IGNORE) . ":$line" : '')
. "
\n";
}
/**
* Dumps variable to plain text.
* @return string
*/
public static function toText($var, array $options = NULL)
{
return htmlspecialchars_decode(strip_tags(self::toHtml($var, $options)), ENT_QUOTES);
}
/**
* Dumps variable to x-terminal.
* @return string
*/
public static function toTerminal($var, array $options = NULL)
{
return htmlspecialchars_decode(strip_tags(preg_replace_callback('#|#', function($m) {
return "\033[" . (isset($m[1], Dumper::$terminalColors[$m[1]]) ? Dumper::$terminalColors[$m[1]] : '0') . "m";
}, self::toHtml($var, $options))), ENT_QUOTES);
}
/**
* Internal toHtml() dump implementation.
* @param mixed variable to dump
* @param array options
* @param int current recursion level
* @return string
*/
private static function dumpVar(& $var, array $options, $level = 0)
{
if (method_exists(__CLASS__, $m = 'dump' . gettype($var))) {
return self::$m($var, $options, $level);
} else {
return "unknown type\n";
}
}
private static function dumpNull()
{
return "NULL\n";
}
private static function dumpBoolean(& $var)
{
return '' . ($var ? 'TRUE' : 'FALSE') . "\n";
}
private static function dumpInteger(& $var)
{
return "$var\n";
}
private static function dumpDouble(& $var)
{
$var = json_encode($var);
return '' . $var . (strpos($var, '.') === FALSE ? '.0' : '') . "\n";
}
private static function dumpString(& $var, $options)
{
return ''
. self::encodeString($options[self::TRUNCATE] && strlen($var) > $options[self::TRUNCATE] ? substr($var, 0, $options[self::TRUNCATE]) . ' ... ' : $var)
. '' . (strlen($var) > 1 ? ' (' . strlen($var) . ')' : '') . "\n";
}
private static function dumpArray(& $var, $options, $level)
{
static $marker;
if ($marker === NULL) {
$marker = uniqid("\x00", TRUE);
}
$out = 'array (';
if (empty($var)) {
return $out . ")\n";
} elseif (isset($var[$marker])) {
return $out . (count($var) - 1) . ") [ RECURSION ]\n";
} elseif (!$options[self::DEPTH] || $level < $options[self::DEPTH]) {
$collapsed = $level ? count($var) >= $options[self::COLLAPSE_COUNT] : $options[self::COLLAPSE];
$out = '' . $out . count($var) . ")\n';
$var[$marker] = TRUE;
foreach ($var as $k => & $v) {
if ($k !== $marker) {
$out .= ' ' . str_repeat('| ', $level) . ''
. '' . (preg_match('#^\w+\z#', $k) ? $k : self::encodeString($k)) . ' => '
. self::dumpVar($v, $options, $level + 1);
}
}
unset($var[$marker]);
return $out . '
';
} else {
return $out . count($var) . ") [ ... ]\n";
}
}
private static function dumpObject(& $var, $options, $level)
{
if ($var instanceof \Closure) {
$rc = new \ReflectionFunction($var);
$fields = array();
foreach ($rc->getParameters() as $param) {
$fields[] = '$' . $param->getName();
}
$fields = array(
'file' => $rc->getFileName(), 'line' => $rc->getStartLine(),
'variables' => $rc->getStaticVariables(), 'parameters' => implode(', ', $fields)
);
} elseif ($var instanceof \SplFileInfo) {
$fields = array('path' => $var->getPathname());
} elseif ($var instanceof \SplObjectStorage) {
$fields = array();
foreach (clone $var as $obj) {
$fields[] = array('object' => $obj, 'data' => $var[$obj]);
}
} else {
$fields = (array) $var;
}
static $list = array();
$rc = $var instanceof \Closure ? new \ReflectionFunction($var) : new \ReflectionClass($var);
$out = 'getFileName() ? ' data-nette-href="' . htmlspecialchars(strtr(Debugger::$editor, array('%file' => rawurlencode($rc->getFileName()), '%line' => $rc->getStartLine()))) . '"' : '')
. '>' . get_class($var) . ' #' . substr(md5(spl_object_hash($var)), 0, 4) . '';
if (empty($fields)) {
return $out . "\n";
} elseif (in_array($var, $list, TRUE)) {
return $out . " { RECURSION }\n";
} elseif (!$options[self::DEPTH] || $level < $options[self::DEPTH] || $var instanceof \Closure) {
$collapsed = $level ? count($fields) >= $options[self::COLLAPSE_COUNT] : $options[self::COLLAPSE];
$out = '' . $out . "\n';
$list[] = $var;
foreach ($fields as $k => & $v) {
$vis = '';
if ($k[0] === "\x00") {
$vis = ' ' . ($k[1] === '*' ? 'protected' : 'private') . '';
$k = substr($k, strrpos($k, "\x00") + 1);
}
$out .= ' ' . str_repeat('| ', $level) . ''
. '' . (preg_match('#^\w+\z#', $k) ? $k : self::encodeString($k)) . "$vis => "
. self::dumpVar($v, $options, $level + 1);
}
array_pop($list);
return $out . '
';
} else {
return $out . " { ... }\n";
}
}
private static function dumpResource(& $var, $options, $level)
{
$type = get_resource_type($var);
$out = '' . htmlSpecialChars($type) . ' resource';
if (isset(self::$resources[$type])) {
$out = "$out\n";
foreach (call_user_func(self::$resources[$type], $var) as $k => $v) {
$out .= ' ' . str_repeat('| ', $level) . ''
. '' . htmlSpecialChars($k) . " => " . self::dumpVar($v, $options, $level + 1);
}
return $out . '
';
}
return "$out\n";
}
private static function encodeString($s)
{
static $table;
if ($table === NULL) {
foreach (array_merge(range("\x00", "\x1F"), range("\x7F", "\xFF")) as $ch) {
$table[$ch] = '\x' . str_pad(dechex(ord($ch)), 2, '0', STR_PAD_LEFT);
}
$table["\\"] = '\\\\';
$table["\r"] = '\r';
$table["\n"] = '\n';
$table["\t"] = '\t';
}
if (preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u', $s) || preg_last_error()) {
$s = strtr($s, $table);
}
return '"' . htmlSpecialChars($s, ENT_NOQUOTES) . '"';
}
/**
* Finds the location where dump was called.
* @return array [file, line, code]
*/
private static function findLocation()
{
foreach (debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE) as $item) {
if (isset($item['file']) && strpos($item['file'], __DIR__) === 0) {
continue;
} elseif (!isset($item['file'], $item['line']) || !is_file($item['file'])) {
break;
} else {
$lines = file($item['file']);
$line = $lines[$item['line'] - 1];
return array(
$item['file'],
$item['line'],
trim(preg_match('#\w*dump(er::\w+)?\(.*\)#i', $line, $m) ? $m[0] : $line)
);
}
}
}
/**
* @return bool
*/
private static function detectColors()
{
return self::$terminalColors &&
(getenv('ConEmuANSI') === 'ON'
|| getenv('ANSICON') !== FALSE
|| (defined('STDOUT') && function_exists('posix_isatty') && posix_isatty(STDOUT)));
}
}
Nette-2.1.0/Nette/Diagnostics/FireLogger.php 100777 0 0 11757 12261522617 14033 0 array());
/**
* Sends message to FireLogger console.
* @param mixed
* @return bool was successful?
*/
public static function log($message, $priority = self::DEBUG)
{
if (!isset($_SERVER['HTTP_X_FIRELOGGER']) || headers_sent()) {
return FALSE;
}
$item = array(
'name' => 'PHP',
'level' => $priority,
'order' => count(self::$payload['logs']),
'time' => str_pad(number_format((microtime(TRUE) - Debugger::$time) * 1000, 1, '.', ' '), 8, '0', STR_PAD_LEFT) . ' ms',
'template' => '',
'message' => '',
'style' => 'background:#767ab6',
);
$args = func_get_args();
if (isset($args[0]) && is_string($args[0])) {
$item['template'] = array_shift($args);
}
if (isset($args[0]) && $args[0] instanceof \Exception) {
$e = array_shift($args);
$trace = $e->getTrace();
if (isset($trace[0]['class']) && $trace[0]['class'] === 'Nette\Diagnostics\Debugger'
&& ($trace[0]['function'] === '_shutdownHandler' || $trace[0]['function'] === '_errorHandler')
) {
unset($trace[0]);
}
$file = str_replace(dirname(dirname(dirname($e->getFile()))), "\xE2\x80\xA6", $e->getFile());
$item['template'] = ($e instanceof \ErrorException ? '' : get_class($e) . ': ')
. $e->getMessage() . ($e->getCode() ? ' #' . $e->getCode() : '') . ' in ' . $file . ':' . $e->getLine();
$item['pathname'] = $e->getFile();
$item['lineno'] = $e->getLine();
} else {
$trace = debug_backtrace();
if (isset($trace[1]['class']) && $trace[1]['class'] === 'Nette\Diagnostics\Debugger'
&& ($trace[1]['function'] === 'fireLog')
) {
unset($trace[0]);
}
foreach ($trace as $frame) {
if (isset($frame['file']) && is_file($frame['file'])) {
$item['pathname'] = $frame['file'];
$item['lineno'] = $frame['line'];
break;
}
}
}
$item['exc_info'] = array('', '', array());
$item['exc_frames'] = array();
foreach ($trace as $frame) {
$frame += array('file' => NULL, 'line' => NULL, 'class' => NULL, 'type' => NULL, 'function' => NULL, 'object' => NULL, 'args' => NULL);
$item['exc_info'][2][] = array($frame['file'], $frame['line'], "$frame[class]$frame[type]$frame[function]", $frame['object']);
$item['exc_frames'][] = $frame['args'];
}
if (isset($args[0]) && in_array($args[0], array(self::DEBUG, self::INFO, self::WARNING, self::ERROR, self::CRITICAL), TRUE)) {
$item['level'] = array_shift($args);
}
$item['args'] = $args;
self::$payload['logs'][] = self::jsonDump($item, -1);
foreach (str_split(base64_encode(@json_encode(self::$payload)), 4990) as $k => $v) { // intentionally @
header("FireLogger-de11e-$k:$v");
}
return TRUE;
}
/**
* Dump implementation for JSON.
* @param mixed variable to dump
* @param int current recursion level
* @return string
*/
private static function jsonDump(& $var, $level = 0)
{
if (is_bool($var) || is_null($var) || is_int($var) || is_float($var)) {
return $var;
} elseif (is_string($var)) {
if (Debugger::$maxLen && strlen($var) > Debugger::$maxLen) {
$var = substr($var, 0, Debugger::$maxLen) . " \xE2\x80\xA6 ";
}
return Nette\Utils\Strings::fixEncoding($var);
} elseif (is_array($var)) {
static $marker;
if ($marker === NULL) {
$marker = uniqid("\x00", TRUE);
}
if (isset($var[$marker])) {
return "\xE2\x80\xA6RECURSION\xE2\x80\xA6";
} elseif ($level < Debugger::$maxDepth || !Debugger::$maxDepth) {
$var[$marker] = TRUE;
$res = array();
foreach ($var as $k => & $v) {
if ($k !== $marker) {
$res[self::jsonDump($k)] = self::jsonDump($v, $level + 1);
}
}
unset($var[$marker]);
return $res;
} else {
return " \xE2\x80\xA6 ";
}
} elseif (is_object($var)) {
$arr = (array) $var;
static $list = array();
if (in_array($var, $list, TRUE)) {
return "\xE2\x80\xA6RECURSION\xE2\x80\xA6";
} elseif ($level < Debugger::$maxDepth || !Debugger::$maxDepth) {
$list[] = $var;
$res = array("\x00" => '(object) ' . get_class($var));
foreach ($arr as $k => & $v) {
if ($k[0] === "\x00") {
$k = substr($k, strrpos($k, "\x00") + 1);
}
$res[self::jsonDump($k)] = self::jsonDump($v, $level + 1);
}
array_pop($list);
return $res;
} else {
return " \xE2\x80\xA6 ";
}
} elseif (is_resource($var)) {
return "resource " . get_resource_type($var);
} else {
return "unknown type";
}
}
}
Nette-2.1.0/Nette/Diagnostics/Helpers.php 100777 0 0 6060 12261522617 13357 0 href(strtr(Debugger::$editor, array('%file' => rawurlencode($file), '%line' => $line)))
->title("$file:$line")
->setHtml(htmlSpecialChars(rtrim($dir, DIRECTORY_SEPARATOR), ENT_IGNORE) . DIRECTORY_SEPARATOR . '' . htmlSpecialChars(basename($file), ENT_IGNORE) . '' . ($line ? ":$line" : ''));
} else {
return Nette\Utils\Html::el('span')->setText($file . ($line ? ":$line" : ''));
}
}
public static function findTrace(array $trace, $method, & $index = NULL)
{
$m = explode('::', $method);
foreach ($trace as $i => $item) {
if (isset($item['function']) && $item['function'] === end($m)
&& isset($item['class']) === isset($m[1])
&& (!isset($item['class']) || $item['class'] === $m[0] || $m[0] === '*' || is_subclass_of($item['class'], $m[0]))
) {
$index = $i;
return $item;
}
}
}
public static function fixStack($exception)
{
if (function_exists('xdebug_get_function_stack')) {
$stack = array();
foreach (array_slice(array_reverse(xdebug_get_function_stack()), 2, -1) as $row) {
$frame = array(
'file' => $row['file'],
'line' => $row['line'],
'function' => isset($row['function']) ? $row['function'] : '*unknown*',
'args' => array(),
);
if (!empty($row['class'])) {
$frame['type'] = isset($row['type']) && $row['type'] === 'dynamic' ? '->' : '::';
$frame['class'] = $row['class'];
}
$stack[] = $frame;
}
$ref = new \ReflectionProperty('Exception', 'trace');
$ref->setAccessible(TRUE);
$ref->setValue($exception, $stack);
}
return $exception;
}
/** @deprecated */
public static function htmlDump($var)
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Diagnostics\Dumper::toHtml() instead.', E_USER_DEPRECATED);
return Dumper::toHtml($var);
}
/** @deprecated */
public static function clickableDump($var)
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Diagnostics\Dumper::toHtml() instead.', E_USER_DEPRECATED);
return Dumper::toHtml($var);
}
/** @deprecated */
public static function textDump($var)
{
trigger_error(__METHOD__ . '() is deprecated; use Nette\Diagnostics\Dumper::toText() instead.', E_USER_DEPRECATED);
return Dumper::toText($var);
}
}
Nette-2.1.0/Nette/Diagnostics/IBarPanel.php 100777 0 0 747 12261522617 13540 0 directory)) {
throw new Nette\DirectoryNotFoundException("Directory '$this->directory' is not found or is not directory.");
}
if (is_array($message)) {
$message = implode(' ', $message);
}
$message = preg_replace('#\s*\r?\n\s*#', ' ', trim($message));
$file = $this->directory . '/' . strtolower($priority ?: self::INFO) . '.log';
$res = (bool) file_put_contents($file, $message . PHP_EOL, FILE_APPEND | LOCK_EX);
if (($priority === self::ERROR || $priority === self::CRITICAL) && $this->email && $this->mailer
&& @filemtime($this->directory . '/email-sent') + $this->emailSnooze < time() // @ - file may not exist
&& @file_put_contents($this->directory . '/email-sent', 'sent') // @ - file may not be writable
) {
call_user_func($this->mailer, $message, implode(', ', (array) $this->email));
}
return $res;
}
/**
* Default mailer.
* @param string
* @param string
* @return void
*/
public static function defaultMailer($message, $email)
{
$host = preg_replace('#[^\w.-]+#', '', isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : php_uname('n'));
$parts = str_replace(
array("\r\n", "\n"),
array("\n", PHP_EOL),
array(
'headers' => implode("\n", array(
"From: noreply@$host",
'X-Mailer: Nette Framework',
'Content-Type: text/plain; charset=UTF-8',
'Content-Transfer-Encoding: 8bit',
)) . "\n",
'subject' => "PHP: An error occurred on the server $host",
'body' => "[" . @date('Y-m-d H:i:s') . "] $message", // @ - timezone may not be set
)
);
mail($email, $parts['subject'], $parts['body'], $parts['headers']);
}
}
Nette-2.1.0/Nette/Diagnostics/OutputDebugger.php 100777 0 0 3155 12261522617 14724 0 start();
}
public function start()
{
foreach (get_included_files() as $file) {
if (fread(fopen($file, 'r'), 3) === self::BOM) {
$this->list[] = array($file, 1, self::BOM);
}
}
ob_start(array($this, 'handler'), PHP_VERSION_ID >= 50400 ? 1 : 2);
}
public function handler($s, $phase)
{
$trace = debug_backtrace(FALSE);
if (isset($trace[0]['file'], $trace[0]['line'])) {
if ($this->lastFile === $trace[0]['file']) {
$this->list[count($this->list) - 1][2] .= $s;
} else {
$this->list[] = array($this->lastFile = $trace[0]['file'], $trace[0]['line'], $s);
}
}
if ($phase === PHP_OUTPUT_HANDLER_FINAL) {
return $this->renderHtml();
}
}
private function renderHtml()
{
$res = '';
foreach ($this->list as $item) {
list($file, $line, $s) = $item;
$res .= Helpers::editorLink($item[0], $item[1]) . ' '
. str_replace(self::BOM, 'BOM', Dumper::toHtml($item[2])) . "
\n";
}
return $res . '
';
}
}
Nette-2.1.0/Nette/Diagnostics/templates/ 40777 0 0 0 12261522617 13140 5 Nette-2.1.0/Nette/Diagnostics/templates/bar.css 100777 0 0 17152 12261522617 14544 0 /**
* Debugger Bar
*
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/
/* common styles */
#nette-debug {
display: none;
direction: ltr;
}
body#nette-debug {
margin: 5px 5px 0;
display: block;
}
body #nette-debug {
position: absolute;
bottom: 0;
right: 0;
}
#nette-debug * {
font: inherit;
color: inherit;
background: transparent;
margin: 0;
padding: 0;
border: none;
text-align: inherit;
list-style: inherit;
opacity: 1;
border-radius: 0;
box-shadow: none;
}
#nette-debug b, #nette-debug strong {
font-weight: bold;
}
#nette-debug i, #nette-debug em {
font-style: italic;
}
#nette-debug a {
color: #125EAE;
text-decoration: none;
}
#nette-debug .nette-panel a {
color: #125EAE;
text-decoration: none;
}
#nette-debug a:hover, #nette-debug a:active, #nette-debug a:focus {
background-color: #125EAE;
color: white;
}
#nette-debug .nette-panel h2, #nette-debug .nette-panel h3, #nette-debug .nette-panel p {
margin: .4em 0;
}
#nette-debug .nette-panel table {
border-collapse: collapse;
background: #FDF5CE;
}
#nette-debug .nette-panel tr:nth-child(2n) td {
background: #F7F0CB;
}
#nette-debug .nette-panel td, #nette-debug .nette-panel th {
border: 1px solid #E6DFBF;
padding: 2px 5px;
vertical-align: top;
text-align: left;
}
#nette-debug .nette-panel th {
background: #F4F3F1;
color: #655E5E;
font-size: 90%;
font-weight: bold;
}
#nette-debug .nette-panel pre, #nette-debug .nette-panel code {
font: 9pt/1.5 Consolas, monospace;
}
#nette-debug table .nette-right {
text-align: right;
}
/* bar */
#nette-debug-bar {
font: normal normal 12px/21px Tahoma, sans-serif;
color: #333;
border: 1px solid #c9c9c9;
background: #EDEAE0 url('data:image/png;base64,R0lGODlhAQAVALMAAOTh1/Px6eHe1fHv5e/s4vLw6Ofk2u3q4PPw6PPx6PDt5PLw5+Dd1OXi2Ojm3Orn3iH5BAAAAAAALAAAAAABABUAAAQPMISEyhpYkfOcaQAgCEwEADs=') top;
position: fixed;
right: 0;
bottom: 0;
overflow: auto;
min-height: 21px;
min-width: 50px;
white-space: nowrap;
z-index: 30000;
opacity: .9;
border-radius: 3px;
box-shadow: 1px 1px 10px rgba(0, 0, 0, .15);
}
#nette-debug-bar:hover {
opacity: 1;
}
#nette-debug-bar ul {
list-style: none none;
margin-left: 4px;
clear: left;
}
#nette-debug-bar li {
float: left;
}
#nette-debug-bar ul.nette-previous li {
font-size: 90%;
opacity: .6;
background: #F5F3EE;
}
#nette-debug-bar ul.nette-previous li:first-child {
width: 45px;
}
#nette-debug-bar img {
vertical-align: middle;
position: relative;
top: -1px;
margin-right: 3px;
}
#nette-debug-bar li a {
color: #000;
display: block;
padding: 0 4px;
}
#nette-debug-bar li a:hover {
color: black;
background: #c3c1b8;
}
#nette-debug-bar li .nette-warning {
color: #D32B2B;
font-weight: bold;
}
#nette-debug-bar li > span {
padding: 0 4px;
}
#nette-debug-logo {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAPCAYAAABwfkanAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABiFJREFUSMe1VglPlGcQ5i+1xjZNqxREtGq8ahCPWsVGvEDBA1BBRQFBDjkE5BYUzwpovRBUREBEBbl3OVaWPfj2vi82eTrvbFHamLRJ4yYTvm+u95mZZ96PoKAv+LOatXBYZ+Bx6uFy6DGnt1m0EOKwSmQzwmHTgX5B/1W+yM9GYJ02CX6/B/5ZF+w2A4x6FYGTYDVp4PdY2Tbrs5N+mnRa2Km4/wV6rhPzQQj5fDc1mJM5nd0iYdZtQWtrCxobGnDpUiledTynbuvg99mgUMhw924Trl2rR01NNSTNJE9iDpTV8innv4K2kZPLroPXbYLHZeSu2K1aeF0muJ2GvwGzmNSwU2E+svm8ZrgdBliMaha/34Vx+RAKCgpwpa4OdbW1UE/L2cc/68WtWzdRVlaG6uoqtD1/BA/pA1MIxLvtes7pc5vhoDOE/rOgbVSdf9aJWa8dBp0Kyg+jdLiTx2vQKWEyqGmcNkqg4iTC1+dzQatWkK+cJqPD7KyFaKEjvRuNjY24fLkGdXW1ePjwAeX4QHonDNI0A75+/RpqqqshH+6F2UAUMaupYXouykV0mp6SQ60coxgL8Z4aMg/4x675/V60v3jKB+Xl5WJibIC4KPEIS0qKqWv5GOh7BZ/HSIk9kA33o7y8DOfPZ6GQOipkXDZAHXKxr4ipqqpkKS6+iIrycgz2dyMnJxtVlZUsotNZWZmor79KBbvgpdjm5sfIzc1hv4L8fKJPDTfJZZc+gRYKr8sAEy2DcBRdEEk62ltx9uwZ5qNILoDU1l6mbrvx5EkzUlKSuTiR7PHjR3x4fv4FyIbeIic7G5WVFUyN+qtX+Lnt2SPcvn2LfURjhF7kE4WPDr+Bx+NEUVEhkpNPoImm5CSOl5aUIC3tLOMR59gtAY4HidGIzj14cB8ZGRkM8kJeHk6cOI4xWR8vSl5uLlJTT6O74xnT5lB8PM6cSYXVqILb5UBWZiYSExMYkE4zzjqX00QHG+h9AjPqMei0k3ywy2khMdNiq6BVCf04T6ekuBgJCUdRUVHOBQwPvkNSUiLjaGi4Q/5qFgYtHgTXRJdTT59GenoaA5gY64deq0Bc3EGuNj4+DnppEheLijhZRkY6SktLsGPHdi6irOwSFTRAgO04deokTSIFsbExuHfvLnFSx8DevelAfFwcA0lJTqZi5PDS9aci/sbE7Oe4wsICbtD27b/ye1NTI3FeSX4W2gdFALRD3A4eM44ePcKViuD79/8gnZP5Kg4+cCAW2dnnqUM2Lujw4UM4ePAA2ztfPsHIYA/sdOt43A50d7UFCjkUj+joXVBMDJDeDhcVk08cjd61C3v37uFYp8PKXX3X8xJRUTtw7FgSn3Xzxg10d7ZCqRjkM+02C7pettDNogqAFjzxuI3YHR2Nffv2coXy0V44HGZERm7kJNu2/cK8bW9rwbp1axnMnj27uUijQQOb1QyTcYZ3YMOGn/Hbzp1crAAvaDfY38O5hW3//n0ce+TIYWiUcub1xo0R2Lp1y8cYsUMWM125VhPe93Zj7do1vEPi26GfUdBFbhK8tGHrli1YsWwpgoOD0dXRQqAtXMCy8DBs3rwJoSGLsWrVclylBdoUGYlVK1dg9eqVCFsSSs8/4btvvmUwEnE0KTERISE/IiIiAsGLF2HhwgU8qbc97QgPX8qFr1mzGgu+/opzdL5o5l1aEhqC9evXYWlYKFYsD6e/YVj0w/dMGZVyBDMqeaDTRuKpkxYjIz2dOyeup6H3r2kkOuJ1H3N5Z1QUzp3LQF9vJ4xGLQYHXiM9LY0pEhsTg+PHj9HNcJu4OcL3uaQZY86LiZw8mcJTkmhBTUYJbU8fcoygobgWR4Z6iKtTPLE7d35HYkICT1dIZuY59HQ9412StBPQTMvw8Z6WaMNFxy3Gab4TeQT0M9IHwUT/G0i0MGIJ9CTiJjBIH+iQaQbC7+QnfEXiQL6xgF09TjETHCt8RbeMuil+D8RNsV1LHdQoZfR/iJJzCZuYmEE/Bd3MJNs/+0UURgFWJJ//aQ8k+CsxVTqnVytHObkQrUoG8T4/bs4u4ubbxLPwFzYNPc8HI2zijLm84l39Dx8hfwJenFezFBKKQwAAAABJRU5ErkJggg==') 0 50% no-repeat;
min-width: 45px;
cursor: move;
}
#nette-debug-logo span {
display: none;
}
/* panels */
#nette-debug .nette-panel {
font: normal normal 12px/1.5 sans-serif;
background: white;
color: #333;
text-align: left;
}
#nette-debug h1 {
font: normal normal 23px/1.4 Tahoma, sans-serif;
color: #575753;
margin: -5px -5px 5px;
padding: 0 25px 5px 5px;
}
#nette-debug .nette-mode-peek .nette-inner, #nette-debug .nette-mode-float .nette-inner {
max-width: 700px;
max-height: 500px;
overflow: auto;
}
#nette-debug .nette-panel .nette-icons {
display: none;
}
#nette-debug .nette-mode-peek {
display: none;
position: fixed;
right: 0;
bottom: 0;
padding: 10px;
min-width: 150px;
min-height: 50px;
border-radius: 5px;
box-shadow: 1px 1px 20px rgba(102, 102, 102, 0.36);
border: 1px solid rgba(0, 0, 0, 0.1);
}
#nette-debug .nette-mode-peek h1 {
cursor: move;
}
#nette-debug .nette-mode-float {
position: fixed;
right: 0;
bottom: 0;
padding: 10px;
min-width: 150px;
min-height: 50px;
border-radius: 5px;
opacity: .95;
box-shadow: 1px 1px 30px rgba(102, 102, 102, 0.36);
border: 1px solid rgba(0, 0, 0, 0.1);
}
#nette-debug .nette-focused {
opacity: 1;
}
#nette-debug .nette-mode-float h1 {
cursor: move;
}
#nette-debug .nette-mode-float .nette-icons {
display: block;
position: absolute;
top: 0;
right: 5px;
font-size: 18px;
}
#nette-debug .nette-icons a {
color: #575753;
}
#nette-debug .nette-icons a:hover {
color: white;
}
/* dump */
#nette-debug pre.nette-dump div {
padding-left: 3ex;
}
#nette-debug pre.nette-dump div div {
border-left: 1px solid rgba(0, 0, 0, .1);
margin-left: .5ex;
}
#nette-debug pre.nette-dump {
background: #FDF5CE;
padding: .4em .7em;
border: 1px dotted silver;
overflow: auto;
}
#nette-debug table pre.nette-dump {
padding: 0;
margin: 0;
border: none;
}
#nette-debug .nette-dump-array, #nette-debug .nette-dump-object {
color: #C22;
}
#nette-debug .nette-dump-string {
color: #35D;
}
#nette-debug .nette-dump-number {
color: #090;
}
#nette-debug .nette-dump-null, #nette-debug .nette-dump-bool {
color: #850;
}
#nette-debug .nette-dump-visibility, #nette-debug .nette-dump-hash {
font-size: 85%; color: #999;
}
#nette-debug .nette-dump-indent {
display: none;
}
@media print {
#nette-debug * {
display: none;
}
}
Nette-2.1.0/Nette/Diagnostics/templates/bar.dumps.panel.phtml 100777 0 0 1502 12261522617 17275 0
Dumped variables
Nette-2.1.0/Nette/Diagnostics/templates/bar.dumps.tab.phtml 100777 0 0 2202 12261522617 16742 0 data)) {
return;
}
?>
variables
Nette-2.1.0/Nette/Diagnostics/templates/bar.errors.panel.phtml 100777 0 0 1305 12261522617 17462 0
Errors
data as $item => $count): list($file, $line, $message) = explode('|', $item, 3) ?>
|
|
Nette-2.1.0/Nette/Diagnostics/templates/bar.errors.tab.phtml 100777 0 0 2441 12261522617 17133 0 data)) {
return;
}
?>
data), $sum > 1 ? ' errors' : ' error' ?>
Nette-2.1.0/Nette/Diagnostics/templates/bar.js 100777 0 0 20571 12261522617 14367 0 /**
* Debugger Bar
*
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/
(function(){
var $ = Nette.Query.factory;
var Panel = Nette.DebugPanel = function(id) {
this.id = 'nette-debug-panel-' + id;
this.elem = $('#' + this.id);
};
Panel.PEEK = 'nette-mode-peek';
Panel.FLOAT = 'nette-mode-float';
Panel.WINDOW = 'nette-mode-window';
Panel.FOCUSED = 'nette-focused';
Panel.zIndex = 20000;
Panel.prototype.init = function() {
var _this = this;
this.elem.data().onmove = function(coords) {
_this.moveConstrains(this, coords);
};
this.elem.draggable({
rightEdge: true,
bottomEdge: true,
handle: this.elem.find('h1'),
stop: function() {
_this.toFloat();
}
}).bind('mouseenter', function() {
_this.focus();
}).bind('mouseleave', function() {
_this.blur();
});
this.elem.find('.nette-icons').find('a').bind('click', function(e) {
if (this.rel === 'close') {
_this.toPeek();
} else {
_this.toWindow();
}
e.preventDefault();
});
this.restorePosition();
};
Panel.prototype.is = function(mode) {
return this.elem.hasClass(mode);
};
Panel.prototype.focus = function(callback) {
var elem = this.elem;
if (this.is(Panel.WINDOW)) {
elem.data().win.focus();
} else {
clearTimeout(elem.data().displayTimeout);
elem.data().displayTimeout = setTimeout(function() {
elem.addClass(Panel.FOCUSED).show();
elem[0].style.zIndex = Panel.zIndex++;
if (callback) {
callback();
}
}, 50);
}
};
Panel.prototype.blur = function() {
var elem = this.elem;
elem.removeClass(Panel.FOCUSED);
if (this.is(Panel.PEEK)) {
clearTimeout(elem.data().displayTimeout);
elem.data().displayTimeout = setTimeout(function() {
elem.hide();
}, 50);
}
};
Panel.prototype.toFloat = function() {
this.elem.removeClass(Panel.WINDOW).
removeClass(Panel.PEEK).
addClass(Panel.FLOAT).
show();
this.reposition();
};
Panel.prototype.toPeek = function() {
this.elem.removeClass(Panel.WINDOW).
removeClass(Panel.FLOAT).
addClass(Panel.PEEK).
hide();
document.cookie = this.id + '=; path=/'; // delete position
};
Panel.prototype.toWindow = function() {
var offset = this.elem.offset();
offset.left += typeof window.screenLeft === 'number' ? window.screenLeft : (window.screenX + 10);
offset.top += typeof window.screenTop === 'number' ? window.screenTop : (window.screenY + 50);
var win = window.open('', this.id.replace(/-/g, '_'), 'left='+offset.left+',top='+offset.top+',width='+offset.width+',height='+(offset.height+15)+',resizable=yes,scrollbars=yes');
if (!win) {
return;
}
var doc = win.document;
doc.write('
- "> Nette Framework
'; ?>
- ', trim($panel['tab']), ''; endif ?>
- ×
Nette-2.1.0/Nette/Diagnostics/templates/bar.time.tab.phtml 100777 0 0 2552 12261522617 16560 0
ms
Nette-2.1.0/Nette/Diagnostics/templates/bluescreen.css 100777 0 0 13621 12261522617 16124 0 /**
* Debugger Bluescreen
*
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/
html {
overflow-y: scroll;
}
body {
margin: 0 0 2em;
padding: 0;
}
#netteBluescreen {
font: 9pt/1.5 Verdana, sans-serif;
background: white;
color: #333;
position: absolute;
left: 0;
top: 0;
width: 100%;
text-align: left;
}
#netteBluescreen * {
font: inherit;
color: inherit;
background: transparent;
border: none;
margin: 0;
padding: 0;
text-align: inherit;
text-indent: 0;
}
#netteBluescreen b {
font-weight: bold;
}
#netteBluescreen i {
font-style: italic;
}
#netteBluescreen a {
text-decoration: none;
color: #328ADC;
padding: 2px 4px;
margin: -2px -4px;
}
#netteBluescreen a:hover, #netteBluescreen a:active, #netteBluescreen a:focus {
color: #085AA3;
}
#netteBluescreenIcon {
position: absolute;
right: .5em;
top: .5em;
z-index: 20000;
text-decoration: none;
background: #CD1818;
color: white !important;
padding: 3px;
}
#netteBluescreenError {
background: #CD1818;
color: white;
font: 13pt/1.5 Verdana, sans-serif !important;
display: block;
}
#netteBluescreenError #netteBsSearch {
color: #CD1818;
font-size: .7em;
}
#netteBluescreenError:hover #netteBsSearch {
color: #ED8383;
}
#netteBluescreen h1 {
font-size: 18pt;
font-weight: normal;
text-shadow: 1px 1px 0 rgba(0, 0, 0, .4);
margin: .7em 0;
}
#netteBluescreen h2 {
font: 14pt/1.5 sans-serif !important;
color: #888;
margin: .6em 0;
}
#netteBluescreen h3 {
font: bold 10pt/1.5 Verdana, sans-serif !important;
margin: 1em 0;
padding: 0;
}
#netteBluescreen p, #netteBluescreen pre {
margin: .8em 0
}
#netteBluescreen pre, #netteBluescreen code, #netteBluescreen table {
font: 9pt/1.5 Consolas, monospace !important;
}
#netteBluescreen pre, #netteBluescreen table {
background: #FDF5CE;
padding: .4em .7em;
border: 1px dotted silver;
overflow: auto;
}
#netteBluescreen table pre {
padding: 0;
margin: 0;
border: none;
}
#netteBluescreen table {
border-collapse: collapse;
width: 100%;
}
#netteBluescreen td, #netteBluescreen th {
vertical-align: top;
text-align: left;
padding: 2px 6px;
border: 1px solid #e6dfbf;
}
#netteBluescreen th {
font-weight: bold;
}
#netteBluescreen tr > :first-child {
width: 20%;
}
#netteBluescreen tr:nth-child(2n), #netteBluescreen tr:nth-child(2n) pre {
background-color: #F7F0CB;
}
#netteBluescreen ol {
margin: 1em 0;
padding-left: 2.5em;
}
#netteBluescreen ul {
font: 7pt/1.5 Verdana, sans-serif !important;
padding: 2em 4em;
margin: 1em 0 0;
color: #777;
background: #F6F5F3 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAAAjCAMAAADbuxbOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADBQTFRF/fz24d7Y7Onj5uLd9vPu3drUzMvG09LN39zW8e7o2NbQ3NnT29jS0M7J1tXQAAAApvmsFgAAABB0Uk5T////////////////////AOAjXRkAAAKlSURBVHja7FbbsqQgDAwENEgc//9vN+SCWDtbtXPmZR/Wc6o02mlC58LA9ckFAOszvMV8xNgyUjyXhojfMVKvRL0ZHavxXYy5JrmchMdzou8YlTClxajtK8ZGGpWRoBr1+gFjKfHkJPbizabLgzE3pH7Iu4K980xgFvlrVzMZoVBWhtvouCDdcTDmTgMCJdVxJ9MKO6XxnliM7hxi5lbj2ZVM4l8DqYyKoNLYcfqBB1/LpHYxEcfVG6ZpMDgyFUVWY/Q1sSYPpIdSAKWqLWL0XqWiMWc4hpH0OQOMOAgdycY4N9Sb7wWANQs3rsDSdLAYiuxi5siVfOhBWIrtH0G3kNaF/8Q4kCPE1kMucG/ZMUBUCOgiKJkPuWWTLGVgLGpwns1DraUayCtoBqERyaYtVsm85NActRooezvSLO/sKZP/nq8n4+xcyjNsRu8zW6KWpdb7wjiQd4WrtFZYFiKHENSmWp6xshh96c2RQ+c7Lt+qbijyEjHWUJ/pZsy8MGIUuzNiPySK2Gqoh6ZTRF6ko6q3nVTkaA//itIrDpW6l3SLo8juOmqMXkYknu5FdQxWbhCfKHEGDhxxyTVaXJF3ZjSl3jMksjSOOKmne9pI+mcG5QvaUJhI9HpkmRo2NpCrDJvsktRhRE2MM6F2n7dt4OaMUq8bCctk0+PoMRzL+1l5PZ2eyM/Owr86gf8z/tOM53lom5+nVcFuB+eJVzlXwAYy9TZ9s537tfqcsJWbEU4nBngZo6FfO9T9CdhfBtmk2dLiAy8uS4zwOpMx2HqYbTC+amNeAYTpsP4SIgvWfUBWXxn3CMHW3ffd7k3+YIkx7w0t/CVGvcPejoeOlzOWzeGbawOHqXQGUTMZRcfj4XPCgW9y/fuvVn8zD9P1QHzv80uAAQA0i3Jer7Jr7gAAAABJRU5ErkJggg==') 99% 10px no-repeat;
border-top: 1px solid #DDD;
}
#netteBluescreen div.panel {
padding: 1px 25px;
}
#netteBluescreen div.inner {
background: #F4F3F1;
padding: .1em 1em 1em;
border-radius: 8px;
}
#netteBluescreen .outer {
overflow: auto;
}
/* source code */
#netteBluescreen pre.php div {
min-width: 100%;
float: left;
white-space: pre;
}
#netteBluescreen .highlight {
background: #CD1818;
color: white;
font-weight: bold;
font-style: normal;
display: block;
padding: 0 .4em;
margin: 0 -.4em;
}
#netteBluescreen .line {
color: #9F9C7F;
font-weight: normal;
font-style: normal;
}
#netteBluescreen a[href^=editor\:] {
color: inherit;
border-bottom: 1px dotted rgba(0, 0, 0, .2);
}
#netteBluescreen span[data-nette-href] {
border-bottom: 1px dotted rgba(0, 0, 0, .2);
}
/* toggle */
html.js #netteBluescreen .nette-collapsed {
display: none;
}
#netteBluescreen .nette-toggle, #netteBluescreen .nette-toggle-collapsed {
cursor: pointer;
}
#netteBluescreen .nette-toggle:after {
content: " ▼";
opacity: .4;
}
#netteBluescreen .nette-toggle-collapsed:after {
content: " ►";
opacity: .4;
}
/* dump */
#netteBluescreen .nette-dump-array, #netteBluescreen .nette-dump-object {
color: #C22;
}
#netteBluescreen .nette-dump-string {
color: #35D;
}
#netteBluescreen .nette-dump-number {
color: #090;
}
#netteBluescreen .nette-dump-null, #netteBluescreen .nette-dump-bool {
color: #850;
}
#netteBluescreen .nette-dump-visibility, #netteBluescreen .nette-dump-hash {
font-size: 85%;
color: #998;
}
#netteBluescreen .nette-dump-indent {
display: none;
}
#netteBluescreen pre.nette-dump div {
padding-left: 3ex;
}
#netteBluescreen pre.nette-dump div div {
border-left: 1px solid rgba(0, 0, 0, .1);
margin-left: .5ex;
}
#netteBluescreen .caused {
float: right;
padding: .3em .6em;
background: #df8075;
border-radius: 0 0 0 8px;
white-space: nowrap;
}
#netteBluescreen .caused a {
color: white;
}
Nette-2.1.0/Nette/Diagnostics/templates/bluescreen.phtml 100777 0 0 47026 12261522617 16466 0 getSeverity()])) ? Debugger::$errorTypes[$exception->getSeverity()] : get_class($exception);
$counter = 0;
?>
getPrevious()): ?>
>
getCode() ? ' #' . $ex->getCode() : '')) ?>
getMessage(), ENT_IGNORE) ?>
getTrace(); $expanded = NULL ?>
getSeverity(), array(E_USER_NOTICE, E_USER_WARNING, E_USER_DEPRECATED))) && $this->isCollapsed($ex->getFile())) {
foreach ($stack as $key => $row) {
if (isset($row['file']) && !$this->isCollapsed($row['file'])) { $expanded = $key; break; }
}
} ?>
File: getFile(), $ex->getLine()) ?>
getFile())): ?>getFile(), $ex->getLine(), 15, $ex instanceof \ErrorException && isset($ex->context) ? $ex->context : NULL) ?>
context) && is_array($ex->context)):?>
context as $k => $v) {
echo '$', htmlspecialchars($k), ' | ', Dumper::toHtml($v), " |
\n";
}
?>
getPrevious()); ?>
' ?>
$v) echo '', htmlspecialchars($k), ' | ', Dumper::toHtml($v), " |
\n";
?>
empty
$v) echo '', htmlspecialchars($k), ' | ', $k === '__NF' ? 'Nette Session' : Dumper::toHtml($v), " |
\n";
?>
$v) echo '', htmlspecialchars($k), ' | ', Dumper::toHtml($v), " |
\n";
?>
$v) {
echo '', htmlspecialchars($k), ' | ';
echo '', Dumper::toHtml($v), " |
\n";
}
?>
', htmlspecialchars($v, ENT_IGNORE), " | \n";
}
?>
|.+\z#s', '', ob_get_clean()) ?>
Headers
$v) echo '', htmlspecialchars($k), ' | ', htmlspecialchars($v), " |
\n";
?>
$
empty
$v) echo '', htmlspecialchars($k), ' | ', Dumper::toHtml($v), " |
\n";
?>
- Report generated at
- PHP
- (revision )